Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp	(revision 38133)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp	(revision 38157)
@@ -20,4 +20,5 @@
 *   Header Files                                                               *
 *******************************************************************************/
+#include <iprt/asm.h>
 #include <iprt/assert.h>
 #include <iprt/getopt.h>
@@ -40,15 +41,50 @@
 /** The semaphore we're blocking on. */
 static RTSEMEVENTMULTI      g_hControlEvent = NIL_RTSEMEVENTMULTI;
-/** The Guest Control service client ID. */
+/** The guest control service client ID. */
 static uint32_t             g_GuestControlSvcClientID = 0;
-/** List of spawned processes. */
-RTLISTNODE                  g_GuestControlExecThreads;
+/** How many started guest processes are kept into memory for supplying
+ *  information to the host. Default is 5 processes. If 0 is specified,
+ *  the maximum number of processes is unlimited. */
+uint32_t                    g_GuestControlProcsMaxKept = 5;
+/** List of guest control threads. */
+RTLISTNODE                  g_GuestControlThreads;
 /** Critical section protecting g_GuestControlExecThreads. */
-RTCRITSECT                  g_GuestControlExecThreadsCritSect;
+RTCRITSECT                  g_GuestControlThreadsCritSect;
 
 /** @copydoc VBOXSERVICE::pfnPreInit */
 static DECLCALLBACK(int) VBoxServiceControlPreInit(void)
 {
+#ifdef VBOX_WITH_GUEST_PROPS
+    /*
+     * Read the service options from the VM's guest properties.
+     * Note that these options can be overridden by the command line options later.
+     */
+    uint32_t uGuestPropSvcClientID;
+    int rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
+    if (RT_FAILURE(rc))
+    {
+        if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
+        {
+            VBoxServiceVerbose(0, "Control: Guest property service is not available, skipping\n");
+            rc = VINF_SUCCESS;
+        }
+        else
+            VBoxServiceError("Control: Failed to connect to the guest property service! Error: %Rrc\n", rc);
+    }
+    else
+    {
+        rc = VBoxServiceReadPropUInt32(uGuestPropSvcClientID, "/VirtualBox/GuestAdd/VBoxService/--control-procs-max-kept",
+                                       &g_GuestControlProcsMaxKept, 0, UINT32_MAX - 1);
+
+        VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
+    }
+
+    if (rc == VERR_NOT_FOUND) /* If a value is not found, don't be sad! */
+        rc = VINF_SUCCESS;
+    return rc;
+#else
+    /* Nothing to do here yet. */
     return VINF_SUCCESS;
+#endif
 }
 
@@ -63,4 +99,7 @@
         rc = VBoxServiceArgUInt32(argc, argv, "", pi,
                                   &g_ControlInterval, 1, UINT32_MAX - 1);
+    else if (!strcmp(argv[*pi], "--control-procs-max-kept"))
+        rc = VBoxServiceArgUInt32(argc, argv, "", pi,
+                                  &g_GuestControlProcsMaxKept, 0, UINT32_MAX - 1);
     return rc;
 }
@@ -83,9 +122,9 @@
     if (RT_SUCCESS(rc))
     {
-        VBoxServiceVerbose(3, "Control: Service Client ID: %#x\n", g_GuestControlSvcClientID);
+        VBoxServiceVerbose(3, "Control: Service client ID: %#x\n", g_GuestControlSvcClientID);
 
         /* Init thread list. */
-        RTListInit(&g_GuestControlExecThreads);
-        rc = RTCritSectInit(&g_GuestControlExecThreadsCritSect);
+        RTListInit(&g_GuestControlThreads);
+        rc = RTCritSectInit(&g_GuestControlThreadsCritSect);
         AssertRC(rc);
     }
@@ -213,4 +252,78 @@
 }
 
+void VBoxServiceControlThreadSignalShutdown(const PVBOXSERVICECTRLTHREAD pThread)
+{
+    AssertPtrReturnVoid(pThread);
+    ASMAtomicXchgBool(&pThread->fShutdown, true);
+}
+
+
+int VBoxServiceControlThreadWaitForShutdown(const PVBOXSERVICECTRLTHREAD pThread)
+{
+    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+    int rc = VINF_SUCCESS;
+    if (pThread->Thread != NIL_RTTHREAD)
+    {
+        /* Wait a bit ... */
+        rc = RTThreadWait(pThread->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL);
+    }
+    return rc;
+}
+
+
+static void VBoxServiceControlDestroyThreads(void)
+{
+    VBoxServiceVerbose(3, "Control: Destroying threads ...\n");
+
+    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
+    if (RT_SUCCESS(rc))
+    {
+        /* Signal all threads that we want to shutdown. */
+        PVBOXSERVICECTRLTHREAD pNode;
+        RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
+            VBoxServiceControlThreadSignalShutdown(pNode);
+
+        /* Wait for threads to shutdown. */
+        RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
+        {
+            int rc2 = VBoxServiceControlThreadWaitForShutdown(pNode);
+            if (RT_FAILURE(rc2))
+                VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2);
+
+            /* Destroy thread specific data. */
+            switch (pNode->enmType)
+            {
+                case kVBoxServiceCtrlThreadDataExec:
+                    VBoxServiceControlExecThreadDataDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData);
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        /* Finally destroy thread list. */
+        pNode = RTListGetFirst(&g_GuestControlThreads, VBOXSERVICECTRLTHREAD, Node);
+        while (pNode)
+        {
+            PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node);
+            bool fLast = RTListNodeIsLast(&g_GuestControlThreads, &pNode->Node);
+
+            RTListNodeRemove(&pNode->Node);
+            RTMemFree(pNode);
+
+            if (fLast)
+                break;
+
+            pNode = pNext;
+        }
+
+        int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
+        if (RT_SUCCESS(rc))
+            rc = rc2;
+    }
+    RTCritSectDelete(&g_GuestControlThreadsCritSect);
+}
+
 
 /** @copydoc VBOXSERVICE::pfnTerm */
@@ -219,5 +332,5 @@
     VBoxServiceVerbose(3, "Control: Terminating ...\n");
 
-    VBoxServiceControlExecThreadsShutdown();
+    VBoxServiceControlDestroyThreads();
 
     VbglR3GuestCtrlDisconnect(g_GuestControlSvcClientID);
@@ -242,9 +355,12 @@
     "Host-driven Guest Control",
     /* pszUsage. */
-   "              [--control-interval <ms>]"
+    "              [--control-interval <ms>] [--control-procs-max-kept <x>]"
     ,
     /* pszOptions. */
     "    --control-interval      Specifies the interval at which to check for\n"
     "                            new control commands. The default is 1000 ms.\n"
+    "    --control-procs-max-kept\n"
+    "                            Specifies how many started guest processes are\n"
+    "                            kept into memory to work with.\n"
     ,
     /* methods */
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp	(revision 38133)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp	(revision 38157)
@@ -47,6 +47,6 @@
 using namespace guestControl;
 
-extern RTLISTNODE g_GuestControlExecThreads;
-extern RTCRITSECT g_GuestControlExecThreadsCritSect;
+extern RTLISTNODE g_GuestControlThreads;
+extern RTCRITSECT g_GuestControlThreadsCritSect;
 
 
@@ -1135,6 +1135,11 @@
                                   const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS)
 {
-    int rc;
-
+    int rc = VBoxServiceControlExecThreadsApplyPolicies();
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /*
+     * Allocate new thread data and assign it to our thread list.
+     */
     PVBOXSERVICECTRLTHREAD pThread = (PVBOXSERVICECTRLTHREAD)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREAD));
     if (pThread)
@@ -1176,10 +1181,10 @@
                 {
                     pThread->fStarted = true;
-                    /*rc =*/ RTListAppend(&g_GuestControlExecThreads, &pThread->Node);
+                    /*rc =*/ RTListAppend(&g_GuestControlThreads, &pThread->Node);
                 }
             }
 
             if (RT_FAILURE(rc))
-                VBoxServiceControlExecThreadDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData);
+                VBoxServiceControlExecThreadDataDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData);
         }
         if (RT_FAILURE(rc))
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp	(revision 38133)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp	(revision 38157)
@@ -20,5 +20,4 @@
 *   Header Files                                                               *
 *******************************************************************************/
-#include <iprt/asm.h>
 #include <iprt/assert.h>
 #include <iprt/getopt.h>
@@ -33,8 +32,10 @@
 #include "VBoxServiceControlExecThread.h"
 
-extern RTLISTNODE g_GuestControlExecThreads;
-extern RTCRITSECT g_GuestControlExecThreadsCritSect;
+extern uint32_t g_GuestControlProcsMaxKept;
+extern RTLISTNODE g_GuestControlThreads;
+extern RTCRITSECT g_GuestControlThreadsCritSect;
 
 const PVBOXSERVICECTRLTHREAD vboxServiceControlExecThreadGetByPID(uint32_t uPID);
+int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread);
 
 /**
@@ -154,5 +155,5 @@
 
     if (RT_FAILURE(rc))
-        VBoxServiceControlExecThreadDestroy(pData);
+        VBoxServiceControlExecThreadDataDestroy(pData);
     return rc;
 }
@@ -160,36 +161,80 @@
 
 /**
- *  Frees an allocated thread data structure along with all its allocated parameters.
- *
- * @param   pData          Pointer to thread data to free.
- */
-void VBoxServiceControlExecThreadDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData)
-{
-    if (pData)
-    {
-        VBoxServiceVerbose(3, "ControlExec: [PID %u]: Destroying thread ...\n",
-                           pData->uPID);
-
-        RTStrFree(pData->pszCmd);
-        if (pData->uNumEnvVars)
-        {
-            for (uint32_t i = 0; i < pData->uNumEnvVars; i++)
-                RTStrFree(pData->papszEnv[i]);
-            RTMemFree(pData->papszEnv);
-        }
-        RTGetOptArgvFree(pData->papszArgs);
-        RTStrFree(pData->pszUser);
-        RTStrFree(pData->pszPassword);
-
-        VBoxServicePipeBufDestroy(&pData->stdOut);
-        VBoxServicePipeBufDestroy(&pData->stdErr);
-        VBoxServicePipeBufDestroy(&pData->stdIn);
-
-        RTMemFree(pData);
-        pData = NULL;
-    }
-}
-
-
+ * Applies the policies to all guest execution threads.
+ *
+ * @return  IPRT status code.
+ */
+int VBoxServiceControlExecThreadsApplyPolicies(void)
+{
+    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
+    if (RT_SUCCESS(rc))
+    {
+        VBoxServiceVerbose(2, "Control: Applying policies ...\n");
+
+        /*
+         * Check if we're respecting our memory policy by checking
+         * how many guest processes are started and served already.
+         */
+        if (g_GuestControlProcsMaxKept) /* If we allow unlimited processes, take a shortcut. */
+        {
+            uint32_t uNumProcs = 0;
+            PVBOXSERVICECTRLTHREAD pNode;
+            RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
+            {
+                if (pNode->enmType == kVBoxServiceCtrlThreadDataExec)
+                    uNumProcs++;
+            }
+
+            /*
+             * Do we serve more guest processes than we should? Kill the oldest n ones (=beginning
+             * at the list).
+             */
+            uint32_t uProcsToKill = 0;
+            if (uNumProcs > g_GuestControlProcsMaxKept)
+                uProcsToKill = uNumProcs - g_GuestControlProcsMaxKept;
+            if (uProcsToKill)
+            {
+                VBoxServiceVerbose(2, "Control: Maximum guest processes set to %u, running %u, killing %u oldest one(s) ...\n",
+                                   g_GuestControlProcsMaxKept, uNumProcs, uProcsToKill);
+
+                RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
+                {
+                    PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node);
+
+                    rc = VBoxServiceControlExecThreadShutdown(pNode);
+                    if (RT_FAILURE(rc))
+                    {
+                        VBoxServiceError("Control: Unable to shut down thread due to policy, rc=%Rrc", rc);
+                        /* Keep going. */
+                    }
+
+                    RTListNodeRemove(&pNode->Node);
+                    RTMemFree(pNode);
+                    pNode = pNext;
+
+                    /* Did we fullfill our rate? Then stop killing innocent guest processes. */
+                    if (--uProcsToKill == 0)
+                        break;
+                }
+            }
+        }
+
+        int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
+        if (RT_SUCCESS(rc))
+            rc = rc2;
+    }
+
+    return rc;
+}
+
+
+/**
+ * Assigns a valid PID to a guest control thread and also checks if there already was
+ * another (stale) guest process which was using that PID before and destroys it.
+ *
+ * @return  IPRT status code.
+ * @param   pData          Pointer to guest control execution thread data.
+ * @param   uPID           PID to assign to the specified guest control execution thread.
+ */
 int VBoxServiceControlExecThreadAssignPID(PVBOXSERVICECTRLTHREADDATAEXEC pData, uint32_t uPID)
 {
@@ -197,19 +242,28 @@
     AssertReturn(uPID, VERR_INVALID_PARAMETER);
 
-    int rc = RTCritSectEnter(&g_GuestControlExecThreadsCritSect);
+    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
     if (RT_SUCCESS(rc))
     {
         /* Search an old thread using the desired PID and shut it down completely -- it's
          * not used anymore. */
-        const PVBOXSERVICECTRLTHREAD pOldThread = vboxServiceControlExecThreadGetByPID(uPID);
-        if (   pOldThread
-            && pOldThread->pvData != pData)
-        {
+        PVBOXSERVICECTRLTHREAD pOldNode = vboxServiceControlExecThreadGetByPID(uPID);
+        if (   pOldNode
+            && pOldNode->pvData != pData)
+        {
+            PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pOldNode->Node, VBOXSERVICECTRLTHREAD, Node);
+
             VBoxServiceVerbose(3, "ControlExec: PID %u was used before, shutting down stale exec thread ...\n",
                                uPID);
-            AssertPtr(pOldThread->pvData);
-            VBoxServiceControlExecThreadDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pOldThread->pvData);
-        }
-        /** @todo Remove node from thread list! */
+            AssertPtr(pOldNode->pvData);
+            rc = VBoxServiceControlExecThreadShutdown(pOldNode);
+            if (RT_FAILURE(rc))
+            {
+                VBoxServiceVerbose(3, "ControlExec: Unable to shut down stale exec thread, rc=%Rrc\n", rc);
+                /* Keep going. */
+            }
+
+            RTListNodeRemove(&pOldNode->Node);
+            RTMemFree(pOldNode);
+        }
 
         /* Assign PID to current thread. */
@@ -219,5 +273,5 @@
         VBoxServicePipeBufSetPID(&pData->stdErr, pData->uPID);
 
-        int rc2 = RTCritSectLeave(&g_GuestControlExecThreadsCritSect);
+        int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -229,4 +283,37 @@
 
 /**
+ *  Frees an allocated thread data structure along with all its allocated parameters.
+ *
+ * @param   pData          Pointer to thread data to free.
+ */
+void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData)
+{
+    if (pData)
+    {
+        VBoxServiceVerbose(3, "ControlExec: [PID %u]: Destroying thread data ...\n",
+                           pData->uPID);
+
+        RTStrFree(pData->pszCmd);
+        if (pData->uNumEnvVars)
+        {
+            for (uint32_t i = 0; i < pData->uNumEnvVars; i++)
+                RTStrFree(pData->papszEnv[i]);
+            RTMemFree(pData->papszEnv);
+        }
+        RTGetOptArgvFree(pData->papszArgs);
+        RTStrFree(pData->pszUser);
+        RTStrFree(pData->pszPassword);
+
+        VBoxServicePipeBufDestroy(&pData->stdOut);
+        VBoxServicePipeBufDestroy(&pData->stdErr);
+        VBoxServicePipeBufDestroy(&pData->stdIn);
+
+        RTMemFree(pData);
+        pData = NULL;
+    }
+}
+
+
+/**
  * Finds a (formerly) started process given by its PID.
  * Internal function, does not do locking -- this must be done from the caller function!
@@ -238,5 +325,5 @@
 {
     PVBOXSERVICECTRLTHREAD pNode = NULL;
-    RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
+    RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
     {
         if (   pNode->fStarted
@@ -267,5 +354,5 @@
     AssertPtrReturn(pBuf, VERR_INVALID_PARAMETER);
 
-    int rc = RTCritSectEnter(&g_GuestControlExecThreadsCritSect);
+    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
     if (RT_SUCCESS(rc))
     {
@@ -295,5 +382,5 @@
         else
             rc = VERR_NOT_FOUND; /* PID not found! */
-        RTCritSectLeave(&g_GuestControlExecThreadsCritSect);
+        RTCritSectLeave(&g_GuestControlThreadsCritSect);
     }
     return rc;
@@ -318,5 +405,5 @@
     AssertReturn(cbSize, VERR_INVALID_PARAMETER);
 
-    int rc = RTCritSectEnter(&g_GuestControlExecThreadsCritSect);
+    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
     if (RT_SUCCESS(rc))
     {
@@ -381,5 +468,5 @@
             rc = VERR_NOT_FOUND; /* PID not found! */
 
-        int rc2 = RTCritSectLeave(&g_GuestControlExecThreadsCritSect);
+        int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -388,63 +475,19 @@
 }
 
-
-/**
- * Gracefully shuts down all process execution threads.
- *
- */
-void VBoxServiceControlExecThreadsShutdown(void)
-{
-    int rc = RTCritSectEnter(&g_GuestControlExecThreadsCritSect);
-    if (RT_SUCCESS(rc))
-    {
-        /* Signal all threads that we want to shutdown. */
-        PVBOXSERVICECTRLTHREAD pNode;
-        RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
-            ASMAtomicXchgBool(&pNode->fShutdown, true);
-
-        /* Wait for threads to shutdown. */
-        RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
-        {
-            if (pNode->Thread != NIL_RTTHREAD)
-            {
-                /* Wait a bit ... */
-                int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL);
-                if (RT_FAILURE(rc2))
-                    VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2);
-            }
-
-            /* Destroy thread specific data. */
-            switch (pNode->enmType)
-            {
-                case kVBoxServiceCtrlThreadDataExec:
-                    VBoxServiceControlExecThreadDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData);
-                    break;
-
-                default:
-                    break;
-            }
-        }
-
-        /* Finally destroy thread list. */
-        pNode = RTListGetFirst(&g_GuestControlExecThreads, VBOXSERVICECTRLTHREAD, Node);
-        while (pNode)
-        {
-            PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node);
-            bool fLast = RTListNodeIsLast(&g_GuestControlExecThreads, &pNode->Node);
-
-            RTListNodeRemove(&pNode->Node);
-            RTMemFree(pNode);
-
-            if (fLast)
-                break;
-
-            pNode = pNext;
-        }
-
-        int rc2 = RTCritSectLeave(&g_GuestControlExecThreadsCritSect);
-        if (RT_SUCCESS(rc))
-            rc = rc2;
-    }
-    RTCritSectDelete(&g_GuestControlExecThreadsCritSect);
-}
-
+int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread)
+{
+    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+
+    if (pThread->enmType == kVBoxServiceCtrlThreadDataExec)
+    {
+        PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
+        if (!pData)
+            return VINF_SUCCESS;
+        VBoxServiceVerbose(2, "Control: [PID %u]: Will not be served anymore\n",
+                           pData->uPID);
+        VBoxServiceControlExecThreadDataDestroy(pData);
+    }
+
+    VBoxServiceControlThreadSignalShutdown(pThread);
+    return VBoxServiceControlThreadWaitForShutdown(pThread);
+}
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h	(revision 38133)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h	(revision 38157)
@@ -27,12 +27,11 @@
                                       const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars,
                                       const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS);
+int VBoxServiceControlExecThreadsApplyPolicies();
 int VBoxServiceControlExecThreadAssignPID(PVBOXSERVICECTRLTHREADDATAEXEC pData, uint32_t uPID);
-void VBoxServiceControlExecThreadDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData);
+void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData);
+int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uint32_t uTimeout,
+                                          uint8_t *pBuf, uint32_t cbSize, uint32_t *pcbRead);
 int VBoxServiceControlExecThreadSetInput(uint32_t uPID, bool fPendingClose, uint8_t *pBuf,
                                          uint32_t cbSize, uint32_t *pcbWritten);
-int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uint32_t uTimeout,
-                                          uint8_t *pBuf, uint32_t cbSize, uint32_t *pcbRead);
-void VBoxServiceControlExecThreadsShutdown(void);
-
 #endif  /* !___VBoxServiceControlExecThread_h */
 
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h	(revision 38133)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h	(revision 38157)
@@ -305,7 +305,6 @@
 
 #ifdef VBOX_WITH_GUEST_CONTROL
-extern int          VBoxServiceGCtrlDirClose(uint32_t u32ClientId, uint32_t uNumParms);
-extern int          VBoxServiceGCtrlDirOpen(uint32_t u32ClientId, uint32_t uNumParms);
-extern int          VBoxServiceGCtrlDirRead(uint32_t u32ClientId, uint32_t uNumParms);
+extern void         VBoxServiceControlThreadSignalShutdown(const PVBOXSERVICECTRLTHREAD pThread);
+extern int          VBoxServiceControlThreadWaitForShutdown(const PVBOXSERVICECTRLTHREAD pThread);
 
 extern int          VBoxServiceControlExecHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms);
@@ -316,5 +315,5 @@
                                                   const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars,
                                                   const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS);
-extern void         VBoxServiceControlExecThreadDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pThread);
+extern void         VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pThread);
 #endif /* VBOX_WITH_GUEST_CONTROL */
 
