Index: /trunk/src/VBox/Main/GuestImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/GuestImpl.cpp	(revision 30074)
+++ /trunk/src/VBox/Main/GuestImpl.cpp	(revision 30075)
@@ -124,10 +124,10 @@
     
         /* Clean up callback data. */
-        CallbackListIter it;
-        for (it = mCallbackList.begin(); it != mCallbackList.end(); it++)
+        CallbackMapIter it;
+        for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++)
             destroyCtrlCallbackContext(it);
     
-        /* Clear process list. */
-        mGuestProcessList.clear();
+        /* Clear process map. */
+        mGuestProcessMap.clear();
     }
 #endif
@@ -550,10 +550,10 @@
 
     AssertPtr(pData);
-    CallbackListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
+    CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
 
     /* Callback can be called several times. */
-    if (it != mCallbackList.end())
-    {
-        PCALLBACKDATAEXECSTATUS pCBData = (PCALLBACKDATAEXECSTATUS)it->pvData;
+    if (it != mCallbackMap.end())
+    {
+        PCALLBACKDATAEXECSTATUS pCBData = (PCALLBACKDATAEXECSTATUS)it->second.pvData;
         AssertPtr(pCBData);
 
@@ -565,6 +565,6 @@
         /* Was progress canceled before? */
         BOOL fCanceled;
-        ComAssert(it->pProgress.isNotNull());
-        it->pProgress->COMGETTER(Canceled)(&fCanceled);
+        ComAssert(it->second.pProgress.isNotNull());
+        it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
 
         Utf8Str errMsg;
@@ -575,5 +575,5 @@
             {
                 case PROC_STS_STARTED:
-                    rc = it->pProgress->SetNextOperation(BstrFmt(tr("Waiting for process to exit ...")), 1 /* Weight */);
+                    rc = it->second.pProgress->SetNextOperation(BstrFmt(tr("Waiting for process to exit ...")), 1 /* Weight */);
                     if (FAILED(rc))
                         errMsg = Utf8StrFmt(Guest::tr("Cannot enter waiting for process exit stage! rc=%u"),
@@ -582,5 +582,5 @@
     
                 case PROC_STS_TEN: /* Terminated normally. */
-                    it->pProgress->notifyComplete(S_OK);
+                    it->second.pProgress->notifyComplete(S_OK);
                     LogFlowFunc(("Proccess (context ID=%u, status=%u) terminated successfully\n",
                                  pData->hdr.u32ContextID, pData->u32Status));
@@ -617,26 +617,25 @@
             }
             
-            /* Handle process list. */
+            /* Handle process map. */
             /** @todo What happens on/deal with PID reuse? */
             /** @todo How to deal with multiple updates at once? */
             if (pCBData->u32PID > 0)
             {
-                GuestProcessIter it_proc = getProcessByPID(pCBData->u32PID);
-                if (it_proc == mGuestProcessList.end())
+                GuestProcessMapIter it_proc = getProcessByPID(pCBData->u32PID);
+                if (it_proc == mGuestProcessMap.end())
                 {
-                    /* Not found, add to list. */
-                    GuestProcess p;
-                    p.mPID = pCBData->u32PID;
-                    p.mStatus = pCBData->u32Status;
-                    p.mExitCode = pCBData->u32Flags; /* Contains exit code. */
-                    p.mFlags = 0;
+                    /* Not found, add to map. */
+                    GuestProcess newProcess;
+                    newProcess.mStatus = pCBData->u32Status;
+                    newProcess.mExitCode = pCBData->u32Flags; /* Contains exit code. */
+                    newProcess.mFlags = 0;
         
-                    mGuestProcessList.push_back(p);
+                    mGuestProcessMap[pCBData->u32PID] = newProcess;
                 }
-                else /* Update list. */
+                else /* Update map. */
                 {
-                    it_proc->mStatus = pCBData->u32Status;
-                    it_proc->mExitCode = pCBData->u32Flags; /* Contains exit code. */
-                    it_proc->mFlags = 0;
+                    it_proc->second.mStatus = pCBData->u32Status;
+                    it_proc->second.mExitCode = pCBData->u32Flags; /* Contains exit code. */
+                    it_proc->second.mFlags = 0;
                 }
             }
@@ -645,10 +644,10 @@
             errMsg = Utf8StrFmt(Guest::tr("Process execution canceled"));
        
-        if (!it->pProgress->getCompleted())
+        if (!it->second.pProgress->getCompleted())
         {
             if (   errMsg.length() 
                 || fCanceled) /* If cancelled we have to report E_FAIL! */
             {
-                it->pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),
+                it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),
                                               (CBSTR)Guest::getComponentName(), errMsg.c_str());
                 LogFlowFunc(("Process (context ID=%u, status=%u) reported error: %s\n",
@@ -671,8 +670,8 @@
 
     AssertPtr(pData);
-    CallbackListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
-    if (it != mCallbackList.end())
-    {
-        PCALLBACKDATAEXECOUT pCBData = (CALLBACKDATAEXECOUT*)it->pvData;
+    CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
+    if (it != mCallbackMap.end())
+    {
+        PCALLBACKDATAEXECOUT pCBData = (CALLBACKDATAEXECOUT*)it->second.pvData;
         AssertPtr(pCBData);
 
@@ -700,11 +699,11 @@
         /* Was progress canceled before? */
         BOOL fCanceled;
-        ComAssert(it->pProgress.isNotNull());
-        it->pProgress->COMGETTER(Canceled)(&fCanceled);
+        ComAssert(it->second.pProgress.isNotNull());
+        it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
 
         if (!fCanceled)
-            it->pProgress->notifyComplete(S_OK);
+            it->second.pProgress->notifyComplete(S_OK);
         else
-            it->pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),
+            it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),
                                           (CBSTR)Guest::getComponentName(), Guest::tr("The output operation was cancelled"));
     }
@@ -720,74 +719,53 @@
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    /** @todo Maybe use a map instead of list for fast context lookup. */
-    CallbackListIter it;
-    for (it = mCallbackList.begin(); it != mCallbackList.end(); it++)
-    {
-        if (it->mContextID == pData->hdr.u32ContextID)
-        {
-            LogFlowFunc(("Client with context ID=%u disconnected\n", it->mContextID));
-            destroyCtrlCallbackContext(it);
-        }
+    CallbackMapIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
+    if (it != mCallbackMap.end())
+    {
+        LogFlowFunc(("Client with context ID=%u disconnected\n", it->first));
+        destroyCtrlCallbackContext(it);
     }
     return rc;
 }
 
-Guest::CallbackListIter Guest::getCtrlCallbackContextByID(uint32_t u32ContextID)
+Guest::CallbackMapIter Guest::getCtrlCallbackContextByID(uint32_t u32ContextID)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);  
+    return mCallbackMap.find(u32ContextID);
+}
+
+Guest::GuestProcessMapIter Guest::getProcessByPID(uint32_t u32PID)
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    /** @todo Maybe use a map instead of list for fast context lookup. */
-    CallbackListIter it;
-    for (it = mCallbackList.begin(); it != mCallbackList.end(); it++)
-    {
-        if (it->mContextID == u32ContextID)
-            return (it);
-    }
-    return it;
-}
-
-Guest::GuestProcessIter Guest::getProcessByPID(uint32_t u32PID)
-{
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    /** @todo Maybe use a map instead of list for fast context lookup. */
-    GuestProcessIter it;
-    for (it = mGuestProcessList.begin(); it != mGuestProcessList.end(); it++)
-    {
-        if (it->mPID == u32PID)
-            return (it);
-    }
-    return it;
+    return mGuestProcessMap.find(u32PID);
 }
 
 /* No locking here; */
-void Guest::destroyCtrlCallbackContext(Guest::CallbackListIter it)
-{
-    if (it->pvData)
-    {
-        LogFlowFunc(("Destroying callback with context ID=%u ...\n", it->mContextID));
-
-        RTMemFree(it->pvData);
-        it->pvData = NULL;
-        it->cbData = 0;
+void Guest::destroyCtrlCallbackContext(Guest::CallbackMapIter it)
+{
+    if (it->second.pvData)
+    {
+        LogFlowFunc(("Destroying callback with context ID=%u ...\n", it->first));
+
+        RTMemFree(it->second.pvData);
+        it->second.pvData = NULL;
+        it->second.cbData = 0;
     }
 
     /* Notify outstanding waits for progress ... */
-    if (it->pProgress && it->pProgress.isNotNull())
-    {
-        LogFlowFunc(("Handling progress of context ID=%u ...\n", it->mContextID));
+    if (it->second.pProgress && it->second.pProgress.isNotNull())
+    {
+        LogFlowFunc(("Handling progress of context ID=%u ...\n", it->first));
 
         BOOL fCompleted;
-        it->pProgress->COMGETTER(Completed)(&fCompleted);
+        it->second.pProgress->COMGETTER(Completed)(&fCompleted);
         if (!fCompleted)
         {
             /* Only cancel if not canceled before! */
             BOOL fCanceled;
-            if (SUCCEEDED(it->pProgress->COMGETTER(Canceled)(&fCanceled)) && !fCanceled)
-                it->pProgress->Cancel();        
+            if (SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled)) && !fCanceled)
+                it->second.pProgress->Cancel();        
 
             /* To get waitForCompletion notified we have to notify it if necessary. */
-            it->pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),
+            it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest),
                                           (CBSTR)Guest::getComponentName(), Guest::tr("The operation was canceled during shutdown"));
         }        
@@ -800,5 +778,5 @@
 
 /* Adds a callback with a user provided data block and an optional progress object
- * to the callback list. A callback is identified by a unique context ID which is used
+ * to the callback map. A callback is identified by a unique context ID which is used
  * to identify a callback from the guest side. */
 uint32_t Guest::addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress *pProgress)
@@ -814,5 +792,5 @@
 
     /* Create a new context ID and assign it. */
-    CallbackListIter it;
+    CallbackMapIter it;
     uint32_t uNewContext = 0;
     do
@@ -824,15 +802,14 @@
         /* Is the context ID already used? */
         it = getCtrlCallbackContextByID(uNewContext);       
-    } while(it != mCallbackList.end());
+    } while(it != mCallbackMap.end());
 
     uint32_t nCallbacks = 0;
-    if (   it == mCallbackList.end()
+    if (   it == mCallbackMap.end()
         && uNewContext > 0)
     {
         /* We apparently got an unused context ID, let's use it! */
-        context.mContextID = uNewContext;
         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-        mCallbackList.push_back(context);
-        nCallbacks = mCallbackList.size();
+        mCallbackMap[uNewContext] = context;
+        nCallbacks = mCallbackMap.size();
     }
     else
@@ -841,5 +818,5 @@
         {
             AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-            nCallbacks = mCallbackList.size();
+            nCallbacks = mCallbackMap.size();
         }
         AssertReleaseMsg(uNewContext, ("No free context ID found! uNewContext=%u, nCallbacks=%u", uNewContext, nCallbacks));
@@ -1021,9 +998,9 @@
                  * get the PID.
                  */
-                CallbackListIter it = getCtrlCallbackContextByID(uContextID);
+                CallbackMapIter it = getCtrlCallbackContextByID(uContextID);
                 BOOL fCanceled = FALSE;
-                if (it != mCallbackList.end())
+                if (it != mCallbackMap.end())
                 {
-                    ComAssert(it->pProgress.isNotNull());
+                    ComAssert(it->second.pProgress.isNotNull());
 
                     /*
@@ -1031,9 +1008,9 @@
                      */
                     PCALLBACKDATAEXECSTATUS pData = NULL;
-                    rc = it->pProgress->WaitForOperationCompletion(0, aTimeoutMS);
+                    rc = it->second.pProgress->WaitForOperationCompletion(0, aTimeoutMS);
                     if (SUCCEEDED(rc))
                     {
                         /* Was the operation canceled by one of the parties? */
-                        rc = it->pProgress->COMGETTER(Canceled)(&fCanceled);
+                        rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
                         if (FAILED(rc)) throw rc;
 
@@ -1042,6 +1019,6 @@
                             AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 
     
-                            pData = (PCALLBACKDATAEXECSTATUS)it->pvData;
-                            Assert(it->cbData == sizeof(CALLBACKDATAEXECSTATUS));
+                            pData = (PCALLBACKDATAEXECSTATUS)it->second.pvData;
+                            Assert(it->second.cbData == sizeof(CALLBACKDATAEXECSTATUS));
                             AssertPtr(pData);
     
@@ -1146,5 +1123,5 @@
                 }
                 else /* Callback context not found; should never happen! */
-                    AssertMsg(it != mCallbackList.end(), ("Callback context with ID %u not found!", uContextID));
+                    AssertMsg(it != mCallbackMap.end(), ("Callback context with ID %u not found!", uContextID));
             }
             else /* HGCM related error codes .*/
@@ -1270,16 +1247,16 @@
              * get the PID.
              */
-            CallbackListIter it = getCtrlCallbackContextByID(uContextID);
+            CallbackMapIter it = getCtrlCallbackContextByID(uContextID);
             BOOL fCanceled = FALSE;
-            if (it != mCallbackList.end())
+            if (it != mCallbackMap.end())
             {
-                ComAssert(it->pProgress.isNotNull());
+                ComAssert(it->second.pProgress.isNotNull());
 
                 /* Wait until operation completed. */
-                rc = it->pProgress->WaitForCompletion(aTimeoutMS);
+                rc = it->second.pProgress->WaitForCompletion(aTimeoutMS);
                 if (FAILED(rc)) throw rc;
                 
                 /* Was the operation canceled by one of the parties? */
-                rc = it->pProgress->COMGETTER(Canceled)(&fCanceled);
+                rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled);
                 if (FAILED(rc)) throw rc;
 
@@ -1287,5 +1264,5 @@
                 {
                     BOOL fCompleted;
-                    if (   SUCCEEDED(it->pProgress->COMGETTER(Completed)(&fCompleted))
+                    if (   SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted))
                         && fCompleted)
                     {
@@ -1293,6 +1270,6 @@
 
                         /* Did we get some output? */
-                        pData = (PCALLBACKDATAEXECOUT)it->pvData;
-                        Assert(it->cbData == sizeof(CALLBACKDATAEXECOUT));
+                        pData = (PCALLBACKDATAEXECOUT)it->second.pvData;
+                        Assert(it->second.cbData == sizeof(CALLBACKDATAEXECOUT));
                         AssertPtr(pData);
 
@@ -1348,5 +1325,5 @@
 
                 /* Remove callback context (not used anymore). */
-                mCallbackList.erase(it);
+                mCallbackMap.erase(it);
             }
             else /* PID lookup failed. */
@@ -1392,16 +1369,10 @@
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-        GuestProcessIterConst it;
-        for (it = mGuestProcessList.begin(); it != mGuestProcessList.end(); it++)
-        {
-            if (it->mPID == aPID)
-                break;
-        }
-
-        if (it != mGuestProcessList.end())
-        {
-            *aExitCode = it->mExitCode;
-            *aFlags = it->mFlags;
-            *aStatus = it->mStatus;
+        GuestProcessMapIterConst it = getProcessByPID(aPID);
+        if (it != mGuestProcessMap.end())
+        {
+            *aExitCode = it->second.mExitCode;
+            *aFlags = it->second.mFlags;
+            *aStatus = it->second.mStatus;
         }
         else
Index: /trunk/src/VBox/Main/include/GuestImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestImpl.h	(revision 30074)
+++ /trunk/src/VBox/Main/include/GuestImpl.h	(revision 30075)
@@ -122,6 +122,4 @@
     struct CallbackContext
     {
-        /** Associated context ID. */
-        uint32_t                    mContextID;
         eVBoxGuestCtrlCallbackType  mType;
         /** Pointer to user-supplied data. */        
@@ -132,18 +130,23 @@
         ComObjPtr<Progress>         pProgress;
     };
-    typedef std::list< CallbackContext > CallbackList;
-    typedef std::list< CallbackContext >::iterator CallbackListIter;
-    typedef std::list< CallbackContext >::const_iterator CallbackListIterConst;
+    /*
+     * The map key is the context ID.
+     */
+    typedef std::map< uint32_t, CallbackContext > CallbackMap;
+    typedef std::map< uint32_t, CallbackContext >::iterator CallbackMapIter;
+    typedef std::map< uint32_t, CallbackContext >::const_iterator CallbackMapIterConst;
 
     struct GuestProcess
     {
-        uint32_t                    mPID;
         uint32_t                    mStatus;
         uint32_t                    mFlags;
         uint32_t                    mExitCode;
     };
-    typedef std::list< GuestProcess > GuestProcessList;
-    typedef std::list< GuestProcess >::iterator GuestProcessIter;
-    typedef std::list< GuestProcess >::const_iterator GuestProcessIterConst;
+    /*
+     * The map key is the PID (process identifier).
+     */
+    typedef std::map< uint32_t, GuestProcess > GuestProcessMap;
+    typedef std::map< uint32_t, GuestProcess >::iterator GuestProcessMapIter;
+    typedef std::map< uint32_t, GuestProcess >::const_iterator GuestProcessMapIterConst;
 
     int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv);
@@ -152,7 +155,7 @@
     int notifyCtrlExecStatus(uint32_t u32Function, PCALLBACKDATAEXECSTATUS pData);
     int notifyCtrlExecOut(uint32_t u32Function, PCALLBACKDATAEXECOUT pData);
-    CallbackListIter getCtrlCallbackContextByID(uint32_t u32ContextID);
-    GuestProcessIter getProcessByPID(uint32_t u32PID);
-    void destroyCtrlCallbackContext(CallbackListIter it);
+    CallbackMapIter getCtrlCallbackContextByID(uint32_t u32ContextID);
+    GuestProcessMapIter getProcessByPID(uint32_t u32PID);
+    void destroyCtrlCallbackContext(CallbackMapIter it);
     uint32_t addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void *pvData, uint32_t cbData, Progress* pProgress);
 # endif
@@ -183,6 +186,6 @@
 
     volatile uint32_t mNextContextID;
-    CallbackList mCallbackList;
-    GuestProcessList mGuestProcessList;
+    CallbackMap mCallbackMap;
+    GuestProcessMap mGuestProcessMap;
 # endif
 };
