Index: /trunk/include/VBox/com/EventQueue.h
===================================================================
--- /trunk/include/VBox/com/EventQueue.h	(revision 22910)
+++ /trunk/include/VBox/com/EventQueue.h	(revision 22911)
@@ -90,7 +90,4 @@
     BOOL waitForEvent (Event **event);
     BOOL handleEvent (Event *event);
-    static int processThreadEventQueue(uint32_t cMsTimeout, bool (*pfnExitCheck)(void *pvUser) = 0,
-                                     void *pvUser = 0, uint32_t cMsPollInterval = 1000,
-                                     bool fReturnOnEvent = true);
     /**
      * Process events pending on this event queue, and wait 
@@ -104,4 +101,9 @@
      */
     int interruptEventQueueProcessing();
+    /**
+     * Get select()'able selector for this event queue, can be -1
+     * on platforms not supporting such functionality.
+     */
+    int getSelectFD();
     /** 
      * Initialize/deinitialize event queues.
Index: /trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp	(revision 22911)
@@ -810,11 +810,8 @@
         }
 
-        /* create an event queue */
-        EventQueue eventQ;
-
         /* initialize global references */
         gSession = session;
         gConsole = console;
-        gEventQ = &eventQ;
+        gEventQ = com::EventQueue::getMainEventQueue();
 
         /* register a callback for machine events */
@@ -919,7 +916,7 @@
 
         Event *e;
-
-        while (eventQ.waitForEvent (&e) && e)
-            eventQ.handleEvent (e);
+        
+        while (gEventQ->waitForEvent (&e) && e)
+          gEventQ->handleEvent (e);
 
         Log (("VBoxHeadless: event loop has terminated...\n"));
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 22911)
@@ -1825,18 +1825,5 @@
     }
 
-    /* create the event queue
-     * (here it is necessary only to process remaining XPCOM/IPC events
-     * after the session is closed) */
-
-#ifdef VBOX_WITH_XPCOM
-    nsCOMPtr<nsIEventQueue> eventQ;
-    NS_GetMainEventQ(getter_AddRefs(eventQ));
-#endif
-
-#ifdef VBOX_WITH_XPCOM
-    HandlerArg handlerArg = { 0, NULL, eventQ, virtualBox, session };
-#else
     HandlerArg handlerArg = { 0, NULL, virtualBox, session };
-#endif
 
     /*
@@ -1917,8 +1904,5 @@
     session->Close();
 
-#ifdef VBOX_WITH_XPCOM
-    eventQ->ProcessPendingEvents();
-#endif
-
+    EventQueue::getMainEventQueue()->processEventQueue(0);
     // end "all-stuff" scope
     ////////////////////////////////////////////////////////////////////////////
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 22911)
@@ -27,13 +27,8 @@
 #include <VBox/com/ptr.h>
 #include <VBox/com/VirtualBox.h>
-#include <VBox/com/EventQueue.h>
 #include <VBox/com/string.h>
 #endif /* !VBOX_ONLY_DOCS */
 
 #include <iprt/types.h>
-
-#if defined(VBOX_WITH_XPCOM) && !defined(RT_OS_DARWIN) && !defined(RT_OS_OS2)
-# define USE_XPCOM_QUEUE
-#endif
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -108,7 +103,4 @@
     char **argv;
 
-#ifdef VBOX_WITH_XPCOM
-    nsCOMPtr<nsIEventQueue> eventQ;
-#endif
 #ifndef VBOX_ONLY_DOCS
     ComPtr<IVirtualBox> virtualBox;
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp	(revision 22911)
@@ -33,4 +33,5 @@
 
 #include <VBox/com/VirtualBox.h>
+#include <VBox/com/EventQueue.h>
 
 #include <VBox/log.h>
@@ -393,18 +394,4 @@
 
 /**
- * Callback for processThreadEventQueue.
- *
- * @param   pvUser  Pointer to the callback object.
- *
- * @returns true if it should return or false if it should continue waiting for
- *          events.
- */
-static bool eventExitCheck(void *pvUser)
-{
-    GuestPropertyCallback const *pCallbacks = (GuestPropertyCallback const *)pvUser;
-    return pCallbacks->Signalled();
-}
-
-/**
  * Enumerates the properties in the guest property store.
  *
@@ -473,13 +460,12 @@
     a->virtualBox->RegisterCallback(callback);
 
-    int vrc = com::EventQueue::processThreadEventQueue(cMsTimeout, eventExitCheck, (void *)cbImpl,
-                                                       1000 /*cMsPollInterval*/, false /*fReturnOnEvent*/);
-    if (   RT_FAILURE(vrc)
-        && vrc != VERR_CALLBACK_RETURN
-        && vrc != VERR_TIMEOUT)
-    {
-        RTPrintf("Error waiting for event: %Rrc\n", vrc);
-        return 1;
-    }
+    do {
+      int vrc = com::EventQueue::getMainEventQueue()->processEventQueue(1000);
+      if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT)
+      {
+          RTPrintf("Error waiting for event: %Rrc\n", vrc);
+          return 1;
+      }
+    } while  (!cbImpl->Signalled());
 
     a->virtualBox->UnregisterCallback(callback);
Index: /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 22911)
@@ -52,7 +52,7 @@
 
 #if defined(VBOX_WITH_XPCOM)
-NS_IMPL_ISUPPORTS1_CI(VBoxSDLFB, IFramebuffer)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VBoxSDLFB, IFramebuffer)
 NS_DECL_CLASSINFO(VBoxSDLFB)
-NS_IMPL_ISUPPORTS1_CI(VBoxSDLFBOverlay, IFramebufferOverlay)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VBoxSDLFBOverlay, IFramebufferOverlay)
 NS_DECL_CLASSINFO(VBoxSDLFBOverlay)
 #endif
Index: /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 22911)
@@ -1012,14 +1012,5 @@
     }
 
-    // create the event queue
-    // (here it is necessary only to process remaining XPCOM/IPC events
-    // after the session is closed)
-    /// @todo
-//    EventQueue eventQ;
-
-#ifdef USE_XPCOM_QUEUE_THREAD
-    nsCOMPtr<nsIEventQueue> eventQ;
-    NS_GetMainEventQ(getter_AddRefs(eventQ));
-#endif /* USE_XPCOM_QUEUE_THREAD */
+    EventQueue* eventQ = com::EventQueue::getMainEventQueue();
 
     /* Get the number of network adapters */
@@ -2043,5 +2034,5 @@
      * event queue buffer!
      */
-    startXPCOMEventQueueThread(eventQ->GetEventQueueSelectFD());
+    startXPCOMEventQueueThread(eventQ->getSelectFD());
 #endif /* USE_XPCOM_QUEUE_THREAD */
 
@@ -2124,5 +2115,5 @@
                     {
                         LogFlow(("SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n"));
-                        eventQ->ProcessPendingEvents();
+                        eventQ->processEventQueue(0);
                         signalXPCOMEventQueueThread();
                         break;
@@ -2156,4 +2147,5 @@
             }
         }
+        eventQ->processEventQueue(0);
     } while (   rc == S_OK
              && (   machineState == MachineState_Starting
@@ -2591,5 +2583,5 @@
             {
                 LogFlow(("SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n"));
-                eventQ->ProcessPendingEvents();
+                eventQ->processEventQueue(0);
                 signalXPCOMEventQueueThread();
                 break;
Index: /trunk/src/VBox/Frontends/VBoxShell/vboxshell.py
===================================================================
--- /trunk/src/VBox/Frontends/VBoxShell/vboxshell.py	(revision 22910)
+++ /trunk/src/VBox/Frontends/VBoxShell/vboxshell.py	(revision 22911)
@@ -218,6 +218,8 @@
             sys.stdout.flush()
             p.waitForCompletion(wait)
+            ctx['global'].waitForEvents(0)
     except KeyboardInterrupt:
         print "Interrupted."
+
 
 def createVm(ctx,name,kind,base):
@@ -1079,5 +1081,5 @@
             if g_verbose:
                 traceback.print_exc()
-
+        ctx['global'].waitForEvents(0)
     try:
         # There is no need to disable metric collection. This is just an example.
Index: /trunk/src/VBox/Main/glue/EventQueue.cpp
===================================================================
--- /trunk/src/VBox/Main/glue/EventQueue.cpp	(revision 22910)
+++ /trunk/src/VBox/Main/glue/EventQueue.cpp	(revision 22911)
@@ -179,6 +179,4 @@
 timedWaitForEventsOnDarwin(nsIEventQueue *pQueue, PRInt32 cMsTimeout)
 {
-  // This deals with the common case where the caller is the main
-  // application thread and the queue is a native one.
   OSStatus       orc       = -1;
   CFTimeInterval rdTimeout = (double)cMsTimeout / 1000;
@@ -200,5 +198,5 @@
 #ifdef RT_OS_WINDOWS
 static int
-processPendingEventsOnWindows()
+processPendingEvents()
 {
     MSG Msg;
@@ -211,5 +209,5 @@
         if (rc == VERR_INTERRUPTED)
             break;
-        rc = VINF_SUCCESS; 
+        rc = VINF_SUCCESS;
     }    
     return rc;
@@ -239,9 +237,17 @@
   }
 };
-#endif
-#include <stdio.h>
+#else
+static int
+processPendingEvents(nsIEventQueue* pQueue)
+{
+  /** @todo: rethink interruption events, current NULL event approach is bad */
+  pQueue->ProcessPendingEvents();
+  return VINF_SUCCESS; 
+}
+#endif
 int EventQueue::processEventQueue(uint32_t cMsTimeout)
 {
     int rc = VINF_SUCCESS;
+    /** @todo: check that current thread == one we were created on */
 #if defined (VBOX_WITH_XPCOM)
     do {
@@ -249,5 +255,5 @@
       nsresult rc;
       
-      rc = mEventQ->PendingEvents(&fHasEvents);
+      rc = mEventQ->PendingEvents(&fHasEvents);     
       if (NS_FAILED (rc))
           return VERR_INTERNAL_ERROR_3;
@@ -305,5 +311,5 @@
     } while (0);
 
-    mEventQ->ProcessPendingEvents();
+    rc = processPendingEvents(mEventQ);
 #else /* Windows */
     do {
@@ -342,12 +348,12 @@
     } while (0);
 
-    processPendingEventsOnWindows();
+    rc = processPendingEvents();
 #endif
     return rc;
-
 }
 
 int EventQueue::interruptEventQueueProcessing()
 {
+    /** @todo: rethink me! */
     postEvent(NULL);
     return VINF_SUCCESS;
@@ -469,251 +475,11 @@
 }
 
-
+int  EventQueue::getSelectFD()
+{
 #ifdef VBOX_WITH_XPCOM
-
-/** Wrapper around nsIEventQueue::PendingEvents. */
-DECLINLINE(bool) hasEventQueuePendingEvents(nsIEventQueue *pQueue)
-{
-    PRBool fHasEvents = PR_FALSE;
-    nsresult rc = pQueue->PendingEvents(&fHasEvents);
-    return NS_SUCCEEDED(rc) && fHasEvents ? true : false;
-}
-
-/** Wrapper around nsIEventQueue::IsQueueNative. */
-DECLINLINE(bool) isEventQueueNative(nsIEventQueue *pQueue)
-{
-    PRBool fIsNative = PR_FALSE;
-    nsresult rc = pQueue->IsQueueNative(&fIsNative);
-    return NS_SUCCEEDED(rc) && fIsNative ? true : false;
-}
-
-/** Wrapper around nsIEventQueue::ProcessPendingEvents. */
-DECLINLINE(void) processPendingEvents(nsIEventQueue *pQueue)
-{
-    pQueue->ProcessPendingEvents();
-}
-
-#else
-
-/** COM version of nsIEventQueue::PendingEvents. */
-DECLINLINE(bool) hasEventQueuePendingEvents(MyThreadHandle &Handle)
-{
-    DWORD rc = MsgWaitForMultipleObjects(1, &Handle.mh, TRUE /*fWaitAll*/, 0 /*ms*/, QS_ALLINPUT);
-    return rc == WAIT_OBJECT_0;
-}
-
-/** COM version of nsIEventQueue::IsQueueNative, the question doesn't make
- *  sense and we have to return false for the code below to work. */
-DECLINLINE(bool) isEventQueueNative(MyThreadHandle const &Handle)
-{
-    return false;
-}
-
-/** COM version of nsIEventQueue::ProcessPendingEvents. */
-static void processPendingEvents(MyThreadHandle const &Handle)
-{
-    /*
-     * Process pending thead messages.
-     */
-    MSG Msg;
-    while (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE))
-    {
-        if (Msg.message == WM_QUIT)
-            return /*VERR_INTERRUPTED*/;
-        DispatchMessage(&Msg);
-    }
-}
-
-#endif /* VBOX_WITH_XPCOM */
-
-/**
- *  Processes events for the current thread.
- *
- *  @param cMsTimeout       The timeout in milliseconds or RT_INDEFINITE_WAIT.
- *  @param pfnExitCheck     Optional callback for checking for some exit condition
- *                          while looping.  Note that this may be called
- *  @param pvUser           User argument for pfnExitCheck.
- *  @param cMsPollInterval  The interval cMsTimeout should be called at. 0 means
- *                          never default.
- *  @param fReturnOnEvent   If true, return immediately after some events has
- *                          been processed. If false, process events until we
- *                          time out, pfnExitCheck returns true, interrupted or
- *                          the queue receives some kind of quit message.
- *
- *  @returns VBox status code.
- *  @retval VINF_SUCCESS if events were processed.
- *  @retval VERR_TIMEOUT if no events before cMsTimeout elapsed.
- *  @retval VERR_INTERRUPTED if the wait was interrupted by a signal or other
- *          async event.
- *  @retval VERR_NOT_FOUND if the thread has no event queue.
- *  @retval VERR_CALLBACK_RETURN if the callback indicates return.
- *
- *  @todo This is just a quick approximation of what we need. Feel free to
- *        improve the interface and make it fit better in with the EventQueue
- *        class.
- */
-/*static*/ int
-EventQueue::processThreadEventQueue(uint32_t cMsTimeout, bool (*pfnExitCheck)(void *pvUser) /*= 0*/,
-                                    void *pvUser /*= 0*/, uint32_t cMsPollInterval /*= 1000*/,
-                                    bool fReturnOnEvent /*= true*/)
-{
-    uint64_t const StartMsTS = RTTimeMilliTS();
-
-    /* set default. */
-    if (cMsPollInterval == 0)
-        cMsPollInterval = 1000;
-
-    /*
-     * Get the event queue / thread.
-     */
-#ifdef VBOX_WITH_XPCOM
-    nsCOMPtr<nsIEventQueue> q;
-    nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(q));
-    if (NS_FAILED(rv))
-        return VERR_NOT_FOUND;
-#else
-    MyThreadHandle q;
-#endif
-
-    /*
-     * Check for pending before setting up the wait.
-     */
-    if (    !hasEventQueuePendingEvents(q)
-        ||  !fReturnOnEvent)
-    {
-        bool fIsNative = isEventQueueNative(q);
-        if (    fIsNative
-            ||  cMsTimeout != RT_INDEFINITE_WAIT
-            ||  pfnExitCheck
-            ||  !fReturnOnEvent /** @todo !fReturnOnEvent and cMsTimeout RT_INDEFINITE_WAIT can be handled in else */)
-        {
-#ifdef USE_XPCOM_QUEUE
-            int const fdQueue = fIsNative ? q->GetEventQueueSelectFD() : -1;
-            if (fIsNative && fdQueue == -1)
-                return VERR_INTERNAL_ERROR_4;
-#endif
-            for (;;)
-            {
-                /*
-                 * Check for events.
-                 */
-                if (hasEventQueuePendingEvents(q))
-                {
-                    if (fReturnOnEvent)
-                        break;
-                    processPendingEvents(q);
-                }
-
-                /*
-                 * Check the user exit.
-                 */
-                if (   pfnExitCheck
-                    && pfnExitCheck(pvUser))
-                    return VERR_CALLBACK_RETURN;
-
-                /*
-                 * Figure out how much we have left to wait and if we've timed out already.
-                 */
-                uint32_t cMsLeft;
-                if (cMsTimeout == RT_INDEFINITE_WAIT)
-                    cMsLeft = RT_INDEFINITE_WAIT;
-                else
-                {
-                    uint64_t cMsElapsed = RTTimeMilliTS() - StartMsTS;
-                    if (cMsElapsed >= cMsTimeout)
-                        break; /* timeout */
-                    cMsLeft = cMsTimeout - (uint32_t)cMsElapsed;
-                }
-
-                /*
-                 * Wait in a queue & platform specific manner.
-                 */
-#ifdef VBOX_WITH_XPCOM
-                if (!fIsNative)
-                    RTThreadSleep(250 /*ms*/);
-                else
-                {
-# ifdef USE_XPCOM_QUEUE
-                    fd_set fdset;
-                    FD_ZERO(&fdset);
-                    FD_SET(fdQueue, &fdset);
-                    struct timeval tv;
-                    if (    cMsLeft == RT_INDEFINITE_WAIT
-                        ||  cMsLeft >= cMsPollInterval)
-                    {
-                        tv.tv_sec = cMsPollInterval / 1000;
-                        tv.tv_usec = (cMsPollInterval % 1000) * 1000;
-                    }
-                    else
-                    {
-                        tv.tv_sec = cMsLeft / 1000;
-                        tv.tv_usec = (cMsLeft % 1000) * 1000;
-                    }
-                    int prc = select(fdQueue + 1, &fdset, NULL, NULL, &tv);
-                    if (prc == -1)
-                        return RTErrConvertFromErrno(errno);
-
-# elif defined(RT_OS_DARWIN)
-                    CFTimeInterval rdTimeout = (double)RT_MIN(cMsLeft, cMsPollInterval) / 1000;
-                    OSStatus orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, rdTimeout, true /*returnAfterSourceHandled*/);
-                    if (orc == kCFRunLoopRunHandledSource)
-                        orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, false /*returnAfterSourceHandled*/);
-                    if (   orc != 0
-                        && orc != kCFRunLoopRunHandledSource
-                        && orc != kCFRunLoopRunTimedOut)
-                        return orc == kCFRunLoopRunStopped || orc == kCFRunLoopRunFinished
-                             ? VERR_INTERRUPTED
-                             : RTErrConvertFromDarwin(orc);
-# else
-#  warning "PORTME:"
-                    RTThreadSleep(250);
-# endif
-                }
-
-#else  /* !VBOX_WITH_XPCOM */
-                DWORD rc = MsgWaitForMultipleObjects(1, &q.mh, TRUE /*fWaitAll*/, RT_MIN(cMsLeft, cMsPollInterval), QS_ALLINPUT);
-                if (rc == WAIT_OBJECT_0)
-                {
-                    if (fReturnOnEvent)
-                        break;
-                    processPendingEvents(q);
-                }
-                else if (rc == WAIT_FAILED)
-                    return RTErrConvertFromWin32(GetLastError());
-                else if (rc != WAIT_TIMEOUT)
-                    return VERR_INTERNAL_ERROR_4;
-#endif /* !VBOX_WITH_XPCOM */
-            } /* for (;;) */
-        }
-        else
-        {
-            /*
-             * Indefinite wait without any complications.
-             */
-#ifdef VBOX_WITH_XPCOM
-            PLEvent *pEvent = NULL;
-            rv = q->WaitForEvent(&pEvent);
-            if (NS_FAILED(rv))
-                return VERR_INTERRUPTED;
-            q->HandleEvent(pEvent);
-#else
-            DWORD rc = MsgWaitForMultipleObjects(1, &q.mh, TRUE /*fWaitAll*/, INFINITE, QS_ALLINPUT);
-            if (rc != WAIT_OBJECT_0)
-            {
-                if (rc == WAIT_FAILED)
-                    return RTErrConvertFromWin32(GetLastError());
-                return VERR_INTERNAL_ERROR_3;
-            }
-#endif
-        }
-    }
-
-    /*
-     * We have/had events in the queue. Process pending events and
-     * return successfully.
-     */
-    processPendingEvents(q);
-
-    return VINF_SUCCESS;
+    return mEventQ->GetEventQueueSelectFD();
+#else
+    return -1;
+#endif
 }
 }
Index: /trunk/src/VBox/Main/webservice/vboxweb.cpp
===================================================================
--- /trunk/src/VBox/Main/webservice/vboxweb.cpp	(revision 22910)
+++ /trunk/src/VBox/Main/webservice/vboxweb.cpp	(revision 22911)
@@ -465,6 +465,6 @@
             soap_end(&soap); // clean up everything and close socket
 
-            // every COM thread needs to process its event queue, or memory leaks
-            int vrc = com::EventQueue::processThreadEventQueue(0);
+            // we have to process main event queue
+            int vrc = com::EventQueue::getMainEventQueue()->processEventQueue(0);
         }
     }
