Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 42382)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 42383)
@@ -12212,4 +12212,7 @@
     }
 
+    /* signal the client watcher thread, because the client is going away */
+    mParent->updateClientWatcher();
+
     LogFlowThisFuncLeave();
     return S_OK;
Index: /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 42382)
+++ /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 42383)
@@ -107,4 +107,10 @@
 // static
 Bstr VirtualBox::sAPIVersion;
+
+#ifdef VBOX_WITH_SYS_V_IPC_SESSION_WATCHER
+/** Table for adaptive timeouts in the client watcher. The counter starts at
+ * the maximum value and decreases to 0. */
+static const RTMSINTERVAL s_updateAdaptTimeouts[] = { 500, 200, 100, 50, 20, 10, 5 };
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -283,4 +289,7 @@
     // the following are data for the client watcher thread
     const UPDATEREQTYPE                 updateReq;
+#ifdef VBOX_WITH_SYS_V_IPC_SESSION_WATCHER
+    uint8_t                             updateAdaptCtr;
+#endif
     const RTTHREAD                      threadClientWatcher;
     typedef std::list<RTPROCESS> ProcessList;
@@ -516,4 +525,5 @@
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
         RTSemEventCreate(&unconst(m->updateReq));
+        ASMAtomicUoWriteU8(&m->updateAdaptCtr, 0);
 #else
 # error "Port me!"
@@ -2627,4 +2637,5 @@
     RTSemEventSignal(m->updateReq);
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+    ASMAtomicUoWriteU8(&m->updateAdaptCtr, RT_ELEMENTS(s_updateAdaptTimeouts) - 1);
     RTSemEventSignal(m->updateReq);
 #else
@@ -4810,5 +4821,22 @@
             autoCaller.release();
 
-            int rc = RTSemEventWait(that->m->updateReq, 500);
+            /* determine wait timeout adaptively: after updating information
+             * relevant to the client watcher, check a few times more
+             * frequently. This ensures good reaction time when the signalling
+             * has to be done a bit before the actual change for technical
+             * reasons, and saves CPU cycles when no activities are expected. */
+            RTMSINTERVAL cMillies;
+            {
+                uint8_t uOld, uNew;
+                do
+                {
+                    uOld = ASMAtomicUoReadU8(&that->m->updateAdaptCtr);
+                    uNew = uOld ? uOld - 1 : uOld;
+                } while (!ASMAtomicCmpXchgU8(&that->m->updateAdaptCtr, uNew, uOld));
+                Assert(uOld <= RT_ELEMENTS(s_updateAdaptTimeouts) - 1);
+                cMillies = s_updateAdaptTimeouts[uOld];
+            }
+
+            int rc = RTSemEventWait(that->m->updateReq, cMillies);
 
             /*
