- Timestamp:
- Sep 15, 2015 3:37:33 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestProperties/service.cpp
r57358 r57766 58 58 #include <string> 59 59 #include <list> 60 61 /** @todo Delete the old !ASYNC_HOST_NOTIFY code and remove this define. */ 62 #define ASYNC_HOST_NOTIFY 60 63 61 64 namespace guestProp { … … 287 290 , mPrevTimestamp(0) 288 291 , mcTimestampAdjustments(0) 292 #ifdef ASYNC_HOST_NOTIFY 293 , mhThreadNotifyHost(NIL_RTTHREAD) 294 , mhReqQNotifyHost(NIL_RTREQQUEUE) 295 #endif 289 296 { } 290 297 … … 365 372 return VINF_SUCCESS; 366 373 } 374 375 #ifdef ASYNC_HOST_NOTIFY 376 int initialize(); 377 #endif 367 378 368 379 private: … … 392 403 void dbgInfoShow(PCDBGFINFOHLP pHlp); 393 404 static DECLCALLBACK(void) dbgInfo(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs); 405 406 #ifdef ASYNC_HOST_NOTIFY 407 /* Thread for handling host notifications. */ 408 RTTHREAD mhThreadNotifyHost; 409 /* Queue for handling requests for notifications. */ 410 RTREQQUEUE mhReqQNotifyHost; 411 static DECLCALLBACK(int) threadNotifyHost(RTTHREAD self, void *pvUser); 412 #endif 394 413 }; 395 414 … … 1208 1227 } 1209 1228 1229 #ifdef ASYNC_HOST_NOTIFY 1230 static DECLCALLBACK(void) notifyHostAsyncWorker(PFNHGCMSVCEXT pfnHostCallback, 1231 void *pvHostData, 1232 HOSTCALLBACKDATA *pHostCallbackData) 1233 { 1234 pfnHostCallback(pvHostData, 0 /*u32Function*/, 1235 (void *)pHostCallbackData, 1236 sizeof(HOSTCALLBACKDATA)); 1237 RTMemFree(pHostCallbackData); 1238 } 1239 #endif 1240 1210 1241 /** 1211 1242 * Notify the service owner that a property has been added/deleted/changed. … … 1221 1252 LogFlowFunc(("pszName=%s, pszValue=%s, u64Timestamp=%llu, pszFlags=%s\n", 1222 1253 pszName, pszValue, u64Timestamp, pszFlags)); 1254 #ifdef ASYNC_HOST_NOTIFY 1255 int rc = VINF_SUCCESS; 1256 1257 /* Allocate buffer for the callback data and strings. */ 1258 size_t cbName = pszName? strlen(pszName): 0; 1259 size_t cbValue = pszValue? strlen(pszValue): 0; 1260 size_t cbFlags = pszFlags? strlen(pszFlags): 0; 1261 size_t cbAlloc = sizeof(HOSTCALLBACKDATA) + cbName + cbValue + cbFlags + 3; 1262 HOSTCALLBACKDATA *pHostCallbackData = (HOSTCALLBACKDATA *)RTMemAlloc(cbAlloc); 1263 if (pHostCallbackData) 1264 { 1265 uint8_t *pu8 = (uint8_t *)pHostCallbackData; 1266 pu8 += sizeof(HOSTCALLBACKDATA); 1267 1268 pHostCallbackData->u32Magic = HOSTCALLBACKMAGIC; 1269 1270 pHostCallbackData->pcszName = (const char *)pu8; 1271 memcpy(pu8, pszName, cbName); 1272 pu8 += cbName; 1273 *pu8++ = 0; 1274 1275 pHostCallbackData->pcszValue = (const char *)pu8; 1276 memcpy(pu8, pszValue, cbValue); 1277 pu8 += cbValue; 1278 *pu8++ = 0; 1279 1280 pHostCallbackData->u64Timestamp = u64Timestamp; 1281 1282 pHostCallbackData->pcszFlags = (const char *)pu8; 1283 memcpy(pu8, pszFlags, cbFlags); 1284 pu8 += cbFlags; 1285 *pu8++ = 0; 1286 1287 rc = RTReqQueueCallEx(mhReqQNotifyHost, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 1288 (PFNRT)notifyHostAsyncWorker, 3, 1289 mpfnHostCallback, mpvHostData, pHostCallbackData); 1290 if (RT_FAILURE(rc)) 1291 { 1292 RTMemFree(pHostCallbackData); 1293 } 1294 } 1295 else 1296 { 1297 rc = VERR_NO_MEMORY; 1298 } 1299 #else 1223 1300 HOSTCALLBACKDATA HostCallbackData; 1224 1301 HostCallbackData.u32Magic = HOSTCALLBACKMAGIC; … … 1230 1307 (void *)(&HostCallbackData), 1231 1308 sizeof(HostCallbackData)); 1309 #endif 1232 1310 LogFlowFunc(("returning rc=%Rrc\n", rc)); 1233 1311 return rc; … … 1440 1518 } 1441 1519 1520 #ifdef ASYNC_HOST_NOTIFY 1521 /* static */ 1522 DECLCALLBACK(int) Service::threadNotifyHost(RTTHREAD self, void *pvUser) 1523 { 1524 Service *pThis = (Service *)pvUser; 1525 int rc = VINF_SUCCESS; 1526 1527 LogFlowFunc(("ENTER: %p\n", pThis)); 1528 1529 for (;;) 1530 { 1531 rc = RTReqQueueProcess(pThis->mhReqQNotifyHost, RT_INDEFINITE_WAIT); 1532 1533 AssertMsg(rc == VWRN_STATE_CHANGED, 1534 ("Left RTReqProcess and error code is not VWRN_STATE_CHANGED rc=%Rrc\n", 1535 rc)); 1536 if (rc == VWRN_STATE_CHANGED) 1537 { 1538 break; 1539 } 1540 } 1541 1542 LogFlowFunc(("LEAVE: %Rrc\n", rc)); 1543 return rc; 1544 } 1545 1546 static DECLCALLBACK(int) wakeupNotifyHost(void) 1547 { 1548 /* Returning a VWRN_* will cause RTReqQueueProcess return. */ 1549 return VWRN_STATE_CHANGED; 1550 } 1551 1552 int Service::initialize() 1553 { 1554 /* The host notification thread and queue. */ 1555 int rc = RTReqQueueCreate(&mhReqQNotifyHost); 1556 if (RT_SUCCESS(rc)) 1557 { 1558 rc = RTThreadCreate(&mhThreadNotifyHost, 1559 threadNotifyHost, 1560 this, 1561 0 /* default stack size */, 1562 RTTHREADTYPE_DEFAULT, 1563 0, /* no flags. */ 1564 "GSTPROPNTFY"); 1565 } 1566 1567 if (RT_FAILURE(rc)) 1568 { 1569 if (mhReqQNotifyHost != NIL_RTREQQUEUE) 1570 { 1571 RTReqQueueDestroy(mhReqQNotifyHost); 1572 mhReqQNotifyHost = NIL_RTREQQUEUE; 1573 } 1574 } 1575 1576 return rc; 1577 } 1578 #endif 1579 1442 1580 int Service::uninit() 1443 1581 { 1582 #ifdef ASYNC_HOST_NOTIFY 1583 if (mhReqQNotifyHost != NIL_RTREQQUEUE) 1584 { 1585 /* Stop the thread */ 1586 PRTREQ pReq; 1587 int rc = RTReqQueueCall(mhReqQNotifyHost, &pReq, 10000, (PFNRT)wakeupNotifyHost, 0); 1588 if (RT_SUCCESS(rc)) 1589 RTReqRelease(pReq); 1590 1591 rc = RTReqQueueDestroy(mhReqQNotifyHost); 1592 AssertRC(rc); 1593 mhReqQNotifyHost = NIL_RTREQQUEUE; 1594 mhThreadNotifyHost = NIL_RTTHREAD; 1595 } 1596 #endif 1597 1444 1598 return VINF_SUCCESS; 1445 1599 } … … 1501 1655 /* Service specific initialization. */ 1502 1656 ptable->pvService = pService; 1657 1658 #ifdef ASYNC_HOST_NOTIFY 1659 rc = pService->initialize(); 1660 if (RT_FAILURE(rc)) 1661 { 1662 delete pService; 1663 pService = NULL; 1664 } 1665 #endif 1503 1666 } 1504 1667 else
Note:
See TracChangeset
for help on using the changeset viewer.