Index: /trunk/src/VBox/Main/src-all/EventImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-all/EventImpl.cpp	(revision 50544)
+++ /trunk/src/VBox/Main/src-all/EventImpl.cpp	(revision 50545)
@@ -595,4 +595,5 @@
     HRESULT dequeue(IEvent **aEvent, LONG aTimeout, AutoLockBase &aAlock);
     HRESULT eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit);
+    void shutdown();
 
     void addRef()
@@ -676,5 +677,5 @@
 struct EventSource::Data
 {
-    Data()
+    Data() : fShutdown(false)
     {}
 
@@ -682,4 +683,5 @@
     EventMap                      mEvMap;
     PendingEventsMap              mPendingMap;
+    bool                          fShutdown;
 };
 
@@ -790,6 +792,6 @@
 
         ::RTCritSectDelete(&mcsQLock);
-        ::RTSemEventDestroy(mQEvent);
-    }
+    }
+    shutdown();
 }
 
@@ -910,4 +912,14 @@
 }
 
+void ListenerRecord::shutdown()
+{
+    if (mQEvent != NIL_RTSEMEVENT)
+    {
+        RTSEMEVENT tmp = mQEvent;
+        mQEvent = NIL_RTSEMEVENT;
+        ::RTSemEventDestroy(tmp);
+    }
+}
+
 EventSource::EventSource()
 {}
@@ -943,4 +955,24 @@
 void EventSource::uninit()
 {
+    {
+        // First of all (before even thinking about entering the uninit span):
+        // make sure that all listeners are are shut down (no pending events or
+        // wait calls), because they cannot be alive without the associated
+        // event source. Otherwise API clients which use long-term (or
+        // indefinite) waits will block VBoxSVC termination (just one example)
+        // for a long time or even infinitely long.
+        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+        if (!m->fShutdown)
+        {
+            m->fShutdown = true;
+            for (Listeners::iterator it = m->mListeners.begin();
+                 it != m->mListeners.end();
+                 ++it)
+            {
+                it->second.obj()->shutdown();
+            }
+        }
+    }
+
     AutoUninitSpan autoUninitSpan(this);
     if (autoUninitSpan.uninitDone())
@@ -964,4 +996,8 @@
     {
         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+        if (m->fShutdown)
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("This event source is already shut down"));
 
         Listeners::const_iterator it = m->mListeners.find(aListener);
@@ -998,4 +1034,5 @@
         if (it != m->mListeners.end())
         {
+            it->second.obj()->shutdown();
             m->mListeners.erase(it);
             // destructor removes refs from the event map
@@ -1036,4 +1073,8 @@
     do {
         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+        if (m->fShutdown)
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("This event source is already shut down"));
 
         VBoxEventType_T evType;
@@ -1083,5 +1124,8 @@
                 Listeners::iterator lit = m->mListeners.find(record.obj()->mListener);
                 if (lit != m->mListeners.end())
+                {
+                    lit->second.obj()->shutdown();
                     m->mListeners.erase(lit);
+                }
             }
             // anything else to do with cbRc?
@@ -1111,4 +1155,8 @@
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (m->fShutdown)
+        return setError(VBOX_E_INVALID_OBJECT_STATE,
+                        tr("This event source is already shut down"));
 
     Listeners::iterator it = m->mListeners.find(aListener);
@@ -1138,4 +1186,8 @@
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (m->fShutdown)
+        return setError(VBOX_E_INVALID_OBJECT_STATE,
+                        tr("This event source is already shut down"));
 
     Listeners::iterator it = m->mListeners.find(aListener);
Index: /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 50544)
+++ /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 50545)
@@ -803,5 +803,9 @@
     if (m->pEventSource)
     {
-        // we don't perform uninit() as it's possible that some pending event refers to this source
+        // Must uninit the event source here, because it makes no sense that
+        // it survives longer than the base object. If someone gets an event
+        // with such an event source then that's life and it has to be dealt
+        // with appropriately on the API client side.
+        m->pEventSource->uninit();
         unconst(m->pEventSource).setNull();
     }
