Changeset 29220 in vbox
- Timestamp:
- May 7, 2010 3:09:53 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 61300
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestControl/service.cpp
r29003 r29220 28 28 29 29 #include <VBox/log.h> 30 #include <iprt/asm.h> 30 #include <iprt/asm.h> /* For ASMBreakpoint(). */ 31 31 #include <iprt/assert.h> 32 32 #include <iprt/cpp/autores.h> … … 65 65 struct GuestCall 66 66 { 67 /** Client ID; a client can have multiple handles! */ 68 uint32_t mClientID; 67 69 /** The call handle */ 68 70 VBOXHGCMCALLHANDLE mHandle; … … 73 75 74 76 /** The standard constructor */ 75 GuestCall() : m Handle(0), mParms(NULL), mNumParms(0) {}77 GuestCall() : mClientID(0), mHandle(0), mParms(NULL), mNumParms(0) {} 76 78 /** The normal contructor */ 77 GuestCall(VBOXHGCMCALLHANDLE aHandle, VBOXHGCMSVCPARM aParms[], int cParms) 78 : mHandle(aHandle), mParms(aParms), mNumParms(cParms) {} 79 GuestCall(uint32_t aClientID, VBOXHGCMCALLHANDLE aHandle, 80 VBOXHGCMSVCPARM aParms[], uint32_t cParms) 81 : mClientID(aClientID), mHandle(aHandle), mParms(aParms), mNumParms(cParms) {} 79 82 }; 80 83 /** The guest call list type */ 81 typedef std::list <GuestCall> CallList; 84 typedef std::list< GuestCall > CallList; 85 typedef std::list< GuestCall >::iterator CallListIter; 86 typedef std::list< GuestCall >::const_iterator CallListIterConst; 82 87 83 88 /** … … 91 96 /** HGCM helper functions. */ 92 97 PVBOXHGCMSVCHELPERS mpHelpers; 93 /** @todo we should have classes for thread and request handler thread */94 /** Queue of outstanding property change notifications */95 RTREQQUEUE *mReqQueue;96 /** Request that we've left pending in a call to flushNotifications. */97 PRTREQ mPendingDummyReq;98 /** Thread for processing the request queue */99 RTTHREAD mReqThread;100 /** Tell the thread that it should exit */101 bool volatile mfExitThread;102 98 /** Callback function supplied by the host for notification of updates 103 99 * to properties */ … … 113 109 explicit Service(PVBOXHGCMSVCHELPERS pHelpers) 114 110 : mpHelpers(pHelpers) 115 , mPendingDummyReq(NULL)116 , mfExitThread(false)117 111 , mpfnHostCallback(NULL) 118 112 , mpvHostData(NULL) 119 113 { 120 int rc = RTReqCreateQueue(&mReqQueue);121 #ifndef VBOX_GUEST_CTRL_TEST_NOTHREAD122 if (RT_SUCCESS(rc))123 rc = RTThreadCreate(&mReqThread, reqThreadFn, this, 0,124 RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,125 "GuestCtrlReq");126 #endif127 if (RT_FAILURE(rc))128 throw rc;129 114 } 130 115 … … 231 216 int paramBufferAssign(PVBOXGUESTCTRPARAMBUFFER pBuf, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 232 217 int prepareExecute(uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 233 static DECLCALLBACK(int) reqThreadFn(RTTHREAD ThreadSelf, void *pvUser);234 218 int clientConnect(uint32_t u32ClientID, void *pvClient); 235 219 int clientDisconnect(uint32_t u32ClientID, void *pvClient); 236 220 int sendHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 237 int retrieveNextHostCmd( VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);221 int retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 238 222 int notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 239 223 int processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); … … 246 230 247 231 248 /**249 * Thread function for processing the request queue250 * @copydoc FNRTTHREAD251 */252 /* static */253 DECLCALLBACK(int) Service::reqThreadFn(RTTHREAD ThreadSelf, void *pvUser)254 {255 SELF *pSelf = reinterpret_cast<SELF *>(pvUser);256 while (!pSelf->mfExitThread)257 RTReqProcess(pSelf->mReqQueue, RT_INDEFINITE_WAIT);258 return VINF_SUCCESS;259 }260 261 232 /** @todo Write some nice doc headers! */ 262 233 /* Stores a HGCM request in an internal buffer (pEx). Needs to be freed later using execBufferFree(). */ … … 265 236 AssertPtr(pBuf); 266 237 int rc = VINF_SUCCESS; 238 239 /* Paranoia. */ 240 if (cParms > 256) 241 cParms = 256; 267 242 268 243 /* … … 392 367 { 393 368 LogFlowFunc(("Client (%ld) disconnected\n", u32ClientID)); 369 /* 370 * Throw out all stale clients. 371 */ 372 CallListIter it = mClientList.begin(); 373 while (it != mClientList.end()) 374 { 375 if (it->mClientID == u32ClientID) 376 it = mClientList.erase(it); 377 else 378 it++; 379 } 394 380 return VINF_SUCCESS; 395 381 } … … 424 410 * defer the guest call until we have something from the host. 425 411 */ 426 int Service::retrieveNextHostCmd(VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 412 int Service::retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHandle, 413 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 427 414 { 428 415 int rc = VINF_SUCCESS; … … 435 422 if (mHostCmds.empty()) /* If command list is empty, defer ... */ 436 423 { 437 mClientList.push_back(GuestCall( callHandle, paParms, cParms));424 mClientList.push_back(GuestCall(u32ClientID, callHandle, paParms, cParms)); 438 425 rc = VINF_HGCM_ASYNC_EXECUTE; 439 426 } … … 535 522 if (!fProcessed) 536 523 { 537 mHostCmds.push_back(newCmd); 538 524 mHostCmds.push_back(newCmd); 525 #if 0 539 526 /* Limit list size by deleting oldest element. */ 540 527 if (mHostCmds.size() > 256) /** @todo Use a define! */ 541 528 mHostCmds.pop_front(); 529 #endif 542 530 } 543 531 } … … 568 556 case GUEST_GET_HOST_MSG: 569 557 LogFlowFunc(("GUEST_GET_HOST_MSG\n")); 570 rc = retrieveNextHostCmd( callHandle, cParms, paParms);558 rc = retrieveNextHostCmd(u32ClientID, callHandle, cParms, paParms); 571 559 break; 572 560 -
trunk/src/VBox/Main/GuestImpl.cpp
r29005 r29220 117 117 CallbackListIter it; 118 118 for (it = mCallbackList.begin(); it != mCallbackList.end(); it++) 119 removeCtrlCallbackContext(it);119 destroyCtrlCallbackContext(it); 120 120 121 121 /* Clear process list. */ … … 467 467 int rc = VINF_SUCCESS; 468 468 469 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 470 469 471 AssertPtr(pData); 470 472 CallbackListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID); … … 473 475 if (it != mCallbackList.end()) 474 476 { 475 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);476 477 477 PHOSTEXECCALLBACKDATA pCBData = (HOSTEXECCALLBACKDATA*)it->pvData; 478 478 AssertPtr(pCBData); … … 581 581 int rc = VINF_SUCCESS; 582 582 583 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 584 583 585 AssertPtr(pData); 584 586 CallbackListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID); … … 589 591 AssertPtr(pCBData); 590 592 591 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);592 593 593 pCBData->u32PID = pData->u32PID; 594 594 pCBData->u32HandleId = pData->u32HandleId; … … 601 601 /* Allocate data buffer and copy it */ 602 602 pCBData->pvData = RTMemAlloc(pData->cbData); 603 pCBData->cbData = pData->cbData; 604 603 605 AssertReturn(pCBData->pvData, VERR_NO_MEMORY); 604 606 memcpy(pCBData->pvData, pData->pvData, pData->cbData); 605 pCBData->cbData = pData->cbData;606 607 } 607 608 else … … 646 647 } 647 648 648 void Guest::removeCtrlCallbackContext(Guest::CallbackListIter it) 649 /* No locking here; */ 650 void Guest::destroyCtrlCallbackContext(Guest::CallbackListIter it) 649 651 { 650 652 LogFlowFuncEnter(); 651 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);652 653 if (it->pvData) 653 654 { … … 678 679 { 679 680 LogFlowFuncEnter(); 680 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);681 681 uint32_t uNewContext = ASMAtomicIncU32(&mNextContextID); 682 682 if (uNewContext == UINT32_MAX) 683 683 ASMAtomicUoWriteU32(&mNextContextID, 1000); 684 684 685 /** @todo Put this stuff into a constructor! */ 685 686 CallbackContext context; 686 687 context.mContextID = uNewContext; … … 691 692 context.pProgress = pProgress; 692 693 693 mCallbackList.push_back(context); 694 if (mCallbackList.size() > 256) /* Don't let the container size get too big! */ 694 uint32_t nCallbacks; 695 { 696 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 697 mCallbackList.push_back(context); 698 nCallbacks = mCallbackList.size(); 699 } 700 701 #if 0 702 if (nCallbacks > 256) /* Don't let the container size get too big! */ 695 703 { 696 704 Guest::CallbackListIter it = mCallbackList.begin(); 697 removeCtrlCallbackContext(it); 698 mCallbackList.erase(it); 699 } 705 destroyCtrlCallbackContext(it); 706 { 707 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 708 mCallbackList.erase(it); 709 } 710 } 711 #endif 700 712 701 713 LogFlowFuncLeave(); … … 823 835 paParms[i++].setUInt32(aTimeoutMS); 824 836 825 /* Make sure mParent is valid, so set a read lock in this scope. */ 826 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 827 828 /* Forward the information to the VMM device. */ 829 AssertPtr(mParent); 830 VMMDev *vmmDev = mParent->getVMMDev(); 837 VMMDev *vmmDev; 838 { 839 /* Make sure mParent is valid, so set the read lock while using. 840 * Do not keep this lock while doing the actual call, because in the meanwhile 841 * another thread could request a write lock which would be a bad idea ... */ 842 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 843 844 /* Forward the information to the VMM device. */ 845 AssertPtr(mParent); 846 vmmDev = mParent->getVMMDev(); 847 } 848 831 849 if (vmmDev) 832 850 { … … 1065 1083 1066 1084 { 1067 /* Make sure mParent is valid, so set the read lock while using. */ 1068 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1069 1070 /* Forward the information to the VMM device. */ 1071 AssertPtr(mParent); 1072 VMMDev *vmmDev = mParent->getVMMDev(); 1085 VMMDev *vmmDev; 1086 { 1087 /* Make sure mParent is valid, so set the read lock while using. 1088 * Do not keep this lock while doing the actual call, because in the meanwhile 1089 * another thread could request a write lock which would be a bad idea ... */ 1090 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1091 1092 /* Forward the information to the VMM device. */ 1093 AssertPtr(mParent); 1094 vmmDev = mParent->getVMMDev(); 1095 } 1096 1073 1097 if (vmmDev) 1074 1098 { … … 1171 1195 } 1172 1196 } 1197 1198 { 1199 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1200 destroyCtrlCallbackContext(it); 1201 } 1173 1202 } 1174 1203 else /* PID lookup failed. */ -
trunk/src/VBox/Main/include/GuestImpl.h
r28800 r29220 151 151 CallbackListIter getCtrlCallbackContextByID(uint32_t u32ContextID); 152 152 GuestProcessIter getProcessByPID(uint32_t u32PID); 153 void removeCtrlCallbackContext(CallbackListIter it);153 void destroyCtrlCallbackContext(CallbackListIter it); 154 154 uint32_t addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress* pProgress); 155 155 # endif
Note:
See TracChangeset
for help on using the changeset viewer.