VirtualBox

Ignore:
Timestamp:
Nov 5, 2015 1:18:21 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
103937
Message:

Main/src-server/xpcom/server.cpp: switch from raw XPCOM event queue use to using NativeEventQueue glue code, which processes Darwin's system events, too.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/xpcom/server.cpp

    r57428 r58579  
    2121#include <nsIComponentRegistrar.h>
    2222
    23 #include <nsEventQueueUtils.h>
    2423#include <nsGenericFactory.h>
    2524
     
    5857#include <nsIGenericFactory.h>
    5958#include <VirtualBox_XPCOM.h>
     59
     60#include "VBox/com/NativeEventQueue.h"
    6061
    6162#include "ApplianceImpl.h"
     
    107108static uint32_t gShutdownDelayMs = 5000;
    108109
    109 static nsCOMPtr<nsIEventQueue> gEventQ  = nsnull;
     110static com::NativeEventQueue *gEventQ   = NULL;
    110111static PRBool volatile gKeepRunning     = PR_TRUE;
    111112static PRBool volatile gAllowSigUsrQuit = PR_TRUE;
    112113
    113114/////////////////////////////////////////////////////////////////////////////
    114 
    115 /**
    116  * Simple but smart PLEvent wrapper.
    117  *
    118  * @note Instances must be always created with <tt>operator new</tt>!
    119  */
    120 class MyEvent
    121 {
    122 public:
    123 
    124     MyEvent()
    125     {
    126         mEv.that = NULL;
    127     };
    128 
    129     /**
    130      * Posts this event to the given message queue. This method may only be
    131      * called once. @note On success, the event will be deleted automatically
    132      * after it is delivered and handled. On failure, the event will delete
    133      * itself before this method returns! The caller must not delete it in
    134      * either case.
    135      */
    136     nsresult postTo(nsIEventQueue *aEventQ)
    137     {
    138         AssertReturn(mEv.that == NULL, NS_ERROR_FAILURE);
    139         AssertReturn(aEventQ, NS_ERROR_FAILURE);
    140         nsresult rv = aEventQ->InitEvent(&mEv.e, NULL,
    141                                          eventHandler, eventDestructor);
    142         if (NS_SUCCEEDED(rv))
    143         {
    144             mEv.that = this;
    145             rv = aEventQ->PostEvent(&mEv.e);
    146             if (NS_SUCCEEDED(rv))
    147                 return rv;
    148         }
    149         delete this;
    150         return rv;
    151     }
    152 
    153     virtual void *handler() = 0;
    154 
    155 private:
    156 
    157     struct Ev
    158     {
    159         PLEvent e;
    160         MyEvent *that;
    161     } mEv;
    162 
    163     static void *PR_CALLBACK eventHandler(PLEvent *self)
    164     {
    165         return reinterpret_cast<Ev *>(self)->that->handler();
    166     }
    167 
    168     static void PR_CALLBACK eventDestructor(PLEvent *self)
    169     {
    170         delete reinterpret_cast<Ev *>(self)->that;
    171     }
    172 };
    173 
    174 ////////////////////////////////////////////////////////////////////////////////
    175115
    176116/**
     
    206146             * (see GetInstance()) */
    207147
    208             PRBool onMainThread = PR_TRUE;
    209             nsCOMPtr<nsIEventQueue> q(gEventQ);
    210             if (q)
    211             {
    212                 q->IsOnCurrentThread(&onMainThread);
    213                 q = nsnull;
    214             }
    215 
     148            bool onMainThread = RTThreadIsMain(RTThreadSelf());
    216149            PRBool timerStarted = PR_FALSE;
    217150
     
    276209    }
    277210
    278     class MaybeQuitEvent : public MyEvent
     211    class MaybeQuitEvent : public NativeEvent
    279212    {
    280213        /* called on the main thread */
     
    335268         * and this method was so lucky that it got a chance to run before
    336269         * the timer was killed. */
    337         nsCOMPtr<nsIEventQueue> q(gEventQ);
     270        com::NativeEventQueue *q = gEventQ;
    338271        AssertReturnVoid(q);
    339272
    340273        /* post a quit event to the main queue */
    341274        MaybeQuitEvent *ev = new MaybeQuitEvent();
    342         nsresult rv = ev->postTo(q);
    343         NOREF(rv);
     275        if (!q->postEvent(ev))
     276            delete ev;
    344277
    345278        /* A failure above means we've been already stopped (for example
     
    559492static const char *g_pszPidFile = NULL;
    560493
    561 class ForceQuitEvent : public MyEvent
     494class ForceQuitEvent : public NativeEvent
    562495{
    563496    void *handler()
     
    576509static void signal_handler(int sig)
    577510{
    578     nsCOMPtr<nsIEventQueue> q(gEventQ);
     511    com::NativeEventQueue *q = gEventQ;
    579512    if (q && gKeepRunning)
    580513    {
     
    584517            {
    585518                VirtualBoxClassFactory::MaybeQuitEvent *ev = new VirtualBoxClassFactory::MaybeQuitEvent();
    586                 ev->postTo(q);
     519                if (!q->postEvent(ev))
     520                    delete ev;
    587521            }
    588522            /* else do nothing */
     
    592526            /* post a force quit event to the queue */
    593527            ForceQuitEvent *ev = new ForceQuitEvent();
    594             ev->postTo(q);
     528            if (!q->postEvent(ev))
     529                delete ev;
    595530        }
    596531    }
     
    843778        }
    844779
    845         /* get the main thread's event queue (afaik, the dconnect service always
    846          * gets created upon XPCOM startup, so it will use the main (this)
    847          * thread's event queue to receive IPC events) */
    848         rc = NS_GetMainEventQ(getter_AddRefs(gEventQ));
    849         if (NS_FAILED(rc))
    850         {
    851             RTMsgError("Failed to get the main event queue! (rc=%Rhrc)", rc);
    852             break;
    853         }
    854 
    855780        nsCOMPtr<ipcIService> ipcServ(do_GetService(IPC_SERVICE_CONTRACTID, &rc));
    856781        if (NS_FAILED(rc))
     
    948873            RTPrintf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno);
    949874
    950         PLEvent *ev;
     875        /* get the main thread's event queue */
     876        gEventQ = com::NativeEventQueue::getMainEventQueue();
     877        if (!gEventQ)
     878        {
     879            RTMsgError("Failed to get the main event queue! (rc=%Rhrc)", rc);
     880            break;
     881        }
     882
    951883        while (gKeepRunning)
    952884        {
    953             gEventQ->WaitForEvent(&ev);
    954             gEventQ->HandleEvent(ev);
    955         }
    956 
    957         /* stop accepting new events. Clients that happen to resolve our
    958          * name and issue a CreateInstance() request after this point will
    959          * get NS_ERROR_ABORT once we handle the remaining messages. As a
    960          * result, they should try to start a new server process. */
    961         gEventQ->StopAcceptingEvents();
     885            vrc = gEventQ->processEventQueue(RT_INDEFINITE_WAIT);
     886            if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT)
     887            {
     888                LogRel(("Failed to wait for events! (rc=%Rrc)", vrc));
     889                break;
     890            }
     891        }
     892
     893        gEventQ = NULL;
     894        RTPrintf("Terminated event loop.\n");
    962895
    963896        /* unregister ourselves. After this point, clients will start a new
    964897         * process because they won't be able to resolve the server name.*/
    965898        gIpcServ->RemoveName(VBOXSVC_IPC_NAME);
    966 
    967         /* process any remaining events. These events may include
    968          * CreateInstance() requests received right before we called
    969          * StopAcceptingEvents() above, and those will fail. */
    970         gEventQ->ProcessPendingEvents();
    971 
    972         RTPrintf("Terminated event loop.\n");
    973899    }
    974900    while (0); // this scopes the nsCOMPtrs
    975901
    976902    NS_IF_RELEASE(gIpcServ);
    977     gEventQ = nsnull;
    978903
    979904    /* no nsCOMPtrs are allowed to be alive when you call com::Shutdown(). */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette