Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 50371)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 50372)
@@ -1373,5 +1373,5 @@
 {
     uint32_t fMatches = VBoxGuestCommonGetAndCleanPendingEventsLocked(pDevExt, pSession, fReqEvents);
-    if (fMatches)
+    if (fMatches || pSession->fPendingCancelWaitEvents)
     {
         RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
@@ -1383,4 +1383,5 @@
         else
             Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
+        pSession->fPendingCancelWaitEvents = false;
         return VINF_SUCCESS;
     }
@@ -1519,4 +1520,9 @@
     PVBOXGUESTWAIT          pSafe;
     int                     rc = 0;
+    /* Was as least one WAITEVENT in process for this session?  If not we
+     * set a flag that the next call should be interrupted immediately.  This
+     * is needed so that a user thread can reliably interrupt another one in a
+     * WAITEVENT loop. */
+    bool                    fCancelledOne = false;
 
     Log(("VBoxGuestCommonIOCtl: CANCEL_ALL_WAITEVENTS\n"));
@@ -1530,4 +1536,5 @@
         if (pWait->pSession == pSession)
         {
+            fCancelledOne = true;
             pWait->fResEvents = UINT32_MAX;
             RTListNodeRemove(&pWait->ListNode);
@@ -1540,4 +1547,6 @@
         }
     }
+    if (!fCancelledOne)
+        pSession->fPendingCancelWaitEvents = true;
     RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
     Assert(rc == 0);
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 50371)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 50372)
@@ -237,4 +237,9 @@
     /* Guest Caps Acquired & Reported by this session */
     uint32_t                    u32AquiredGuestCaps;
+    /** Whether a CANCEL_ALL_WAITEVENTS is pending.  This happens when
+     * CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process
+     * in the current session.  In that case the next call will be interrupted
+     * at once. */
+    bool volatile               fPendingCancelWaitEvents;
 } VBOXGUESTSESSION;
 
