- Timestamp:
- Jun 7, 2010 2:10:25 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 62447
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/GuestImpl.cpp
r30071 r30075 124 124 125 125 /* Clean up callback data. */ 126 Callback ListIter it;127 for (it = mCallback List.begin(); it != mCallbackList.end(); it++)126 CallbackMapIter it; 127 for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++) 128 128 destroyCtrlCallbackContext(it); 129 129 130 /* Clear process list. */131 mGuestProcess List.clear();130 /* Clear process map. */ 131 mGuestProcessMap.clear(); 132 132 } 133 133 #endif … … 550 550 551 551 AssertPtr(pData); 552 Callback ListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);552 CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID); 553 553 554 554 /* Callback can be called several times. */ 555 if (it != mCallback List.end())556 { 557 PCALLBACKDATAEXECSTATUS pCBData = (PCALLBACKDATAEXECSTATUS)it-> pvData;555 if (it != mCallbackMap.end()) 556 { 557 PCALLBACKDATAEXECSTATUS pCBData = (PCALLBACKDATAEXECSTATUS)it->second.pvData; 558 558 AssertPtr(pCBData); 559 559 … … 565 565 /* Was progress canceled before? */ 566 566 BOOL fCanceled; 567 ComAssert(it-> pProgress.isNotNull());568 it-> pProgress->COMGETTER(Canceled)(&fCanceled);567 ComAssert(it->second.pProgress.isNotNull()); 568 it->second.pProgress->COMGETTER(Canceled)(&fCanceled); 569 569 570 570 Utf8Str errMsg; … … 575 575 { 576 576 case PROC_STS_STARTED: 577 rc = it-> pProgress->SetNextOperation(BstrFmt(tr("Waiting for process to exit ...")), 1 /* Weight */);577 rc = it->second.pProgress->SetNextOperation(BstrFmt(tr("Waiting for process to exit ...")), 1 /* Weight */); 578 578 if (FAILED(rc)) 579 579 errMsg = Utf8StrFmt(Guest::tr("Cannot enter waiting for process exit stage! rc=%u"), … … 582 582 583 583 case PROC_STS_TEN: /* Terminated normally. */ 584 it-> pProgress->notifyComplete(S_OK);584 it->second.pProgress->notifyComplete(S_OK); 585 585 LogFlowFunc(("Proccess (context ID=%u, status=%u) terminated successfully\n", 586 586 pData->hdr.u32ContextID, pData->u32Status)); … … 617 617 } 618 618 619 /* Handle process list. */619 /* Handle process map. */ 620 620 /** @todo What happens on/deal with PID reuse? */ 621 621 /** @todo How to deal with multiple updates at once? */ 622 622 if (pCBData->u32PID > 0) 623 623 { 624 GuestProcess Iter it_proc = getProcessByPID(pCBData->u32PID);625 if (it_proc == mGuestProcess List.end())624 GuestProcessMapIter it_proc = getProcessByPID(pCBData->u32PID); 625 if (it_proc == mGuestProcessMap.end()) 626 626 { 627 /* Not found, add to list. */ 628 GuestProcess p; 629 p.mPID = pCBData->u32PID; 630 p.mStatus = pCBData->u32Status; 631 p.mExitCode = pCBData->u32Flags; /* Contains exit code. */ 632 p.mFlags = 0; 627 /* Not found, add to map. */ 628 GuestProcess newProcess; 629 newProcess.mStatus = pCBData->u32Status; 630 newProcess.mExitCode = pCBData->u32Flags; /* Contains exit code. */ 631 newProcess.mFlags = 0; 633 632 634 mGuestProcess List.push_back(p);633 mGuestProcessMap[pCBData->u32PID] = newProcess; 635 634 } 636 else /* Update list. */635 else /* Update map. */ 637 636 { 638 it_proc-> mStatus = pCBData->u32Status;639 it_proc-> mExitCode = pCBData->u32Flags; /* Contains exit code. */640 it_proc-> mFlags = 0;637 it_proc->second.mStatus = pCBData->u32Status; 638 it_proc->second.mExitCode = pCBData->u32Flags; /* Contains exit code. */ 639 it_proc->second.mFlags = 0; 641 640 } 642 641 } … … 645 644 errMsg = Utf8StrFmt(Guest::tr("Process execution canceled")); 646 645 647 if (!it-> pProgress->getCompleted())646 if (!it->second.pProgress->getCompleted()) 648 647 { 649 648 if ( errMsg.length() 650 649 || fCanceled) /* If cancelled we have to report E_FAIL! */ 651 650 { 652 it-> pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),651 it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), 653 652 (CBSTR)Guest::getComponentName(), errMsg.c_str()); 654 653 LogFlowFunc(("Process (context ID=%u, status=%u) reported error: %s\n", … … 671 670 672 671 AssertPtr(pData); 673 Callback ListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);674 if (it != mCallback List.end())675 { 676 PCALLBACKDATAEXECOUT pCBData = (CALLBACKDATAEXECOUT*)it-> pvData;672 CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID); 673 if (it != mCallbackMap.end()) 674 { 675 PCALLBACKDATAEXECOUT pCBData = (CALLBACKDATAEXECOUT*)it->second.pvData; 677 676 AssertPtr(pCBData); 678 677 … … 700 699 /* Was progress canceled before? */ 701 700 BOOL fCanceled; 702 ComAssert(it-> pProgress.isNotNull());703 it-> pProgress->COMGETTER(Canceled)(&fCanceled);701 ComAssert(it->second.pProgress.isNotNull()); 702 it->second.pProgress->COMGETTER(Canceled)(&fCanceled); 704 703 705 704 if (!fCanceled) 706 it-> pProgress->notifyComplete(S_OK);705 it->second.pProgress->notifyComplete(S_OK); 707 706 else 708 it-> pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),707 it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), 709 708 (CBSTR)Guest::getComponentName(), Guest::tr("The output operation was cancelled")); 710 709 } … … 720 719 721 720 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 722 723 /** @todo Maybe use a map instead of list for fast context lookup. */ 724 CallbackListIter it; 725 for (it = mCallbackList.begin(); it != mCallbackList.end(); it++) 726 { 727 if (it->mContextID == pData->hdr.u32ContextID) 728 { 729 LogFlowFunc(("Client with context ID=%u disconnected\n", it->mContextID)); 730 destroyCtrlCallbackContext(it); 731 } 721 CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID); 722 if (it != mCallbackMap.end()) 723 { 724 LogFlowFunc(("Client with context ID=%u disconnected\n", it->first)); 725 destroyCtrlCallbackContext(it); 732 726 } 733 727 return rc; 734 728 } 735 729 736 Guest::CallbackListIter Guest::getCtrlCallbackContextByID(uint32_t u32ContextID) 730 Guest::CallbackMapIter Guest::getCtrlCallbackContextByID(uint32_t u32ContextID) 731 { 732 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 733 return mCallbackMap.find(u32ContextID); 734 } 735 736 Guest::GuestProcessMapIter Guest::getProcessByPID(uint32_t u32PID) 737 737 { 738 738 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 739 740 /** @todo Maybe use a map instead of list for fast context lookup. */ 741 CallbackListIter it; 742 for (it = mCallbackList.begin(); it != mCallbackList.end(); it++) 743 { 744 if (it->mContextID == u32ContextID) 745 return (it); 746 } 747 return it; 748 } 749 750 Guest::GuestProcessIter Guest::getProcessByPID(uint32_t u32PID) 751 { 752 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 753 754 /** @todo Maybe use a map instead of list for fast context lookup. */ 755 GuestProcessIter it; 756 for (it = mGuestProcessList.begin(); it != mGuestProcessList.end(); it++) 757 { 758 if (it->mPID == u32PID) 759 return (it); 760 } 761 return it; 739 return mGuestProcessMap.find(u32PID); 762 740 } 763 741 764 742 /* No locking here; */ 765 void Guest::destroyCtrlCallbackContext(Guest::Callback ListIter it)766 { 767 if (it-> pvData)768 { 769 LogFlowFunc(("Destroying callback with context ID=%u ...\n", it-> mContextID));770 771 RTMemFree(it-> pvData);772 it-> pvData = NULL;773 it-> cbData = 0;743 void Guest::destroyCtrlCallbackContext(Guest::CallbackMapIter it) 744 { 745 if (it->second.pvData) 746 { 747 LogFlowFunc(("Destroying callback with context ID=%u ...\n", it->first)); 748 749 RTMemFree(it->second.pvData); 750 it->second.pvData = NULL; 751 it->second.cbData = 0; 774 752 } 775 753 776 754 /* Notify outstanding waits for progress ... */ 777 if (it-> pProgress && it->pProgress.isNotNull())778 { 779 LogFlowFunc(("Handling progress of context ID=%u ...\n", it-> mContextID));755 if (it->second.pProgress && it->second.pProgress.isNotNull()) 756 { 757 LogFlowFunc(("Handling progress of context ID=%u ...\n", it->first)); 780 758 781 759 BOOL fCompleted; 782 it-> pProgress->COMGETTER(Completed)(&fCompleted);760 it->second.pProgress->COMGETTER(Completed)(&fCompleted); 783 761 if (!fCompleted) 784 762 { 785 763 /* Only cancel if not canceled before! */ 786 764 BOOL fCanceled; 787 if (SUCCEEDED(it-> pProgress->COMGETTER(Canceled)(&fCanceled)) && !fCanceled)788 it-> pProgress->Cancel();765 if (SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled)) && !fCanceled) 766 it->second.pProgress->Cancel(); 789 767 790 768 /* To get waitForCompletion notified we have to notify it if necessary. */ 791 it-> pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),769 it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), 792 770 (CBSTR)Guest::getComponentName(), Guest::tr("The operation was canceled during shutdown")); 793 771 } … … 800 778 801 779 /* Adds a callback with a user provided data block and an optional progress object 802 * to the callback list. A callback is identified by a unique context ID which is used780 * to the callback map. A callback is identified by a unique context ID which is used 803 781 * to identify a callback from the guest side. */ 804 782 uint32_t Guest::addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress *pProgress) … … 814 792 815 793 /* Create a new context ID and assign it. */ 816 Callback ListIter it;794 CallbackMapIter it; 817 795 uint32_t uNewContext = 0; 818 796 do … … 824 802 /* Is the context ID already used? */ 825 803 it = getCtrlCallbackContextByID(uNewContext); 826 } while(it != mCallback List.end());804 } while(it != mCallbackMap.end()); 827 805 828 806 uint32_t nCallbacks = 0; 829 if ( it == mCallback List.end()807 if ( it == mCallbackMap.end() 830 808 && uNewContext > 0) 831 809 { 832 810 /* We apparently got an unused context ID, let's use it! */ 833 context.mContextID = uNewContext;834 811 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 835 mCallback List.push_back(context);836 nCallbacks = mCallback List.size();812 mCallbackMap[uNewContext] = context; 813 nCallbacks = mCallbackMap.size(); 837 814 } 838 815 else … … 841 818 { 842 819 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 843 nCallbacks = mCallback List.size();820 nCallbacks = mCallbackMap.size(); 844 821 } 845 822 AssertReleaseMsg(uNewContext, ("No free context ID found! uNewContext=%u, nCallbacks=%u", uNewContext, nCallbacks)); … … 1021 998 * get the PID. 1022 999 */ 1023 Callback ListIter it = getCtrlCallbackContextByID(uContextID);1000 CallbackMapIter it = getCtrlCallbackContextByID(uContextID); 1024 1001 BOOL fCanceled = FALSE; 1025 if (it != mCallback List.end())1002 if (it != mCallbackMap.end()) 1026 1003 { 1027 ComAssert(it-> pProgress.isNotNull());1004 ComAssert(it->second.pProgress.isNotNull()); 1028 1005 1029 1006 /* … … 1031 1008 */ 1032 1009 PCALLBACKDATAEXECSTATUS pData = NULL; 1033 rc = it-> pProgress->WaitForOperationCompletion(0, aTimeoutMS);1010 rc = it->second.pProgress->WaitForOperationCompletion(0, aTimeoutMS); 1034 1011 if (SUCCEEDED(rc)) 1035 1012 { 1036 1013 /* Was the operation canceled by one of the parties? */ 1037 rc = it-> pProgress->COMGETTER(Canceled)(&fCanceled);1014 rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled); 1038 1015 if (FAILED(rc)) throw rc; 1039 1016 … … 1042 1019 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1043 1020 1044 pData = (PCALLBACKDATAEXECSTATUS)it-> pvData;1045 Assert(it-> cbData == sizeof(CALLBACKDATAEXECSTATUS));1021 pData = (PCALLBACKDATAEXECSTATUS)it->second.pvData; 1022 Assert(it->second.cbData == sizeof(CALLBACKDATAEXECSTATUS)); 1046 1023 AssertPtr(pData); 1047 1024 … … 1146 1123 } 1147 1124 else /* Callback context not found; should never happen! */ 1148 AssertMsg(it != mCallback List.end(), ("Callback context with ID %u not found!", uContextID));1125 AssertMsg(it != mCallbackMap.end(), ("Callback context with ID %u not found!", uContextID)); 1149 1126 } 1150 1127 else /* HGCM related error codes .*/ … … 1270 1247 * get the PID. 1271 1248 */ 1272 Callback ListIter it = getCtrlCallbackContextByID(uContextID);1249 CallbackMapIter it = getCtrlCallbackContextByID(uContextID); 1273 1250 BOOL fCanceled = FALSE; 1274 if (it != mCallback List.end())1251 if (it != mCallbackMap.end()) 1275 1252 { 1276 ComAssert(it-> pProgress.isNotNull());1253 ComAssert(it->second.pProgress.isNotNull()); 1277 1254 1278 1255 /* Wait until operation completed. */ 1279 rc = it-> pProgress->WaitForCompletion(aTimeoutMS);1256 rc = it->second.pProgress->WaitForCompletion(aTimeoutMS); 1280 1257 if (FAILED(rc)) throw rc; 1281 1258 1282 1259 /* Was the operation canceled by one of the parties? */ 1283 rc = it-> pProgress->COMGETTER(Canceled)(&fCanceled);1260 rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled); 1284 1261 if (FAILED(rc)) throw rc; 1285 1262 … … 1287 1264 { 1288 1265 BOOL fCompleted; 1289 if ( SUCCEEDED(it-> pProgress->COMGETTER(Completed)(&fCompleted))1266 if ( SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted)) 1290 1267 && fCompleted) 1291 1268 { … … 1293 1270 1294 1271 /* Did we get some output? */ 1295 pData = (PCALLBACKDATAEXECOUT)it-> pvData;1296 Assert(it-> cbData == sizeof(CALLBACKDATAEXECOUT));1272 pData = (PCALLBACKDATAEXECOUT)it->second.pvData; 1273 Assert(it->second.cbData == sizeof(CALLBACKDATAEXECOUT)); 1297 1274 AssertPtr(pData); 1298 1275 … … 1348 1325 1349 1326 /* Remove callback context (not used anymore). */ 1350 mCallback List.erase(it);1327 mCallbackMap.erase(it); 1351 1328 } 1352 1329 else /* PID lookup failed. */ … … 1392 1369 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1393 1370 1394 GuestProcessIterConst it; 1395 for (it = mGuestProcessList.begin(); it != mGuestProcessList.end(); it++) 1396 { 1397 if (it->mPID == aPID) 1398 break; 1399 } 1400 1401 if (it != mGuestProcessList.end()) 1402 { 1403 *aExitCode = it->mExitCode; 1404 *aFlags = it->mFlags; 1405 *aStatus = it->mStatus; 1371 GuestProcessMapIterConst it = getProcessByPID(aPID); 1372 if (it != mGuestProcessMap.end()) 1373 { 1374 *aExitCode = it->second.mExitCode; 1375 *aFlags = it->second.mFlags; 1376 *aStatus = it->second.mStatus; 1406 1377 } 1407 1378 else -
trunk/src/VBox/Main/include/GuestImpl.h
r30020 r30075 122 122 struct CallbackContext 123 123 { 124 /** Associated context ID. */125 uint32_t mContextID;126 124 eVBoxGuestCtrlCallbackType mType; 127 125 /** Pointer to user-supplied data. */ … … 132 130 ComObjPtr<Progress> pProgress; 133 131 }; 134 typedef std::list< CallbackContext > CallbackList; 135 typedef std::list< CallbackContext >::iterator CallbackListIter; 136 typedef std::list< CallbackContext >::const_iterator CallbackListIterConst; 132 /* 133 * The map key is the context ID. 134 */ 135 typedef std::map< uint32_t, CallbackContext > CallbackMap; 136 typedef std::map< uint32_t, CallbackContext >::iterator CallbackMapIter; 137 typedef std::map< uint32_t, CallbackContext >::const_iterator CallbackMapIterConst; 137 138 138 139 struct GuestProcess 139 140 { 140 uint32_t mPID;141 141 uint32_t mStatus; 142 142 uint32_t mFlags; 143 143 uint32_t mExitCode; 144 144 }; 145 typedef std::list< GuestProcess > GuestProcessList; 146 typedef std::list< GuestProcess >::iterator GuestProcessIter; 147 typedef std::list< GuestProcess >::const_iterator GuestProcessIterConst; 145 /* 146 * The map key is the PID (process identifier). 147 */ 148 typedef std::map< uint32_t, GuestProcess > GuestProcessMap; 149 typedef std::map< uint32_t, GuestProcess >::iterator GuestProcessMapIter; 150 typedef std::map< uint32_t, GuestProcess >::const_iterator GuestProcessMapIterConst; 148 151 149 152 int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv); … … 152 155 int notifyCtrlExecStatus(uint32_t u32Function, PCALLBACKDATAEXECSTATUS pData); 153 156 int notifyCtrlExecOut(uint32_t u32Function, PCALLBACKDATAEXECOUT pData); 154 Callback ListIter getCtrlCallbackContextByID(uint32_t u32ContextID);155 GuestProcess Iter getProcessByPID(uint32_t u32PID);156 void destroyCtrlCallbackContext(Callback ListIter it);157 CallbackMapIter getCtrlCallbackContextByID(uint32_t u32ContextID); 158 GuestProcessMapIter getProcessByPID(uint32_t u32PID); 159 void destroyCtrlCallbackContext(CallbackMapIter it); 157 160 uint32_t addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress* pProgress); 158 161 # endif … … 183 186 184 187 volatile uint32_t mNextContextID; 185 Callback List mCallbackList;186 GuestProcess List mGuestProcessList;188 CallbackMap mCallbackMap; 189 GuestProcessMap mGuestProcessMap; 187 190 # endif 188 191 };
Note:
See TracChangeset
for help on using the changeset viewer.