VirtualBox

Changeset 50545 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 21, 2014 2:50:41 PM (11 years ago)
Author:
vboxsync
Message:

Main/EventSource+VirtualBox: better event source cleanup (for now used only in iVirtualBox/VBoxSVC), to prevent sabotage by passive event listener calls hanging around

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-all/EventImpl.cpp

    r50544 r50545  
    595595    HRESULT dequeue(IEvent **aEvent, LONG aTimeout, AutoLockBase &aAlock);
    596596    HRESULT eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit);
     597    void shutdown();
    597598
    598599    void addRef()
     
    676677struct EventSource::Data
    677678{
    678     Data()
     679    Data() : fShutdown(false)
    679680    {}
    680681
     
    682683    EventMap                      mEvMap;
    683684    PendingEventsMap              mPendingMap;
     685    bool                          fShutdown;
    684686};
    685687
     
    790792
    791793        ::RTCritSectDelete(&mcsQLock);
    792         ::RTSemEventDestroy(mQEvent);
    793     }
     794    }
     795    shutdown();
    794796}
    795797
     
    910912}
    911913
     914void ListenerRecord::shutdown()
     915{
     916    if (mQEvent != NIL_RTSEMEVENT)
     917    {
     918        RTSEMEVENT tmp = mQEvent;
     919        mQEvent = NIL_RTSEMEVENT;
     920        ::RTSemEventDestroy(tmp);
     921    }
     922}
     923
    912924EventSource::EventSource()
    913925{}
     
    943955void EventSource::uninit()
    944956{
     957    {
     958        // First of all (before even thinking about entering the uninit span):
     959        // make sure that all listeners are are shut down (no pending events or
     960        // wait calls), because they cannot be alive without the associated
     961        // event source. Otherwise API clients which use long-term (or
     962        // indefinite) waits will block VBoxSVC termination (just one example)
     963        // for a long time or even infinitely long.
     964        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     965        if (!m->fShutdown)
     966        {
     967            m->fShutdown = true;
     968            for (Listeners::iterator it = m->mListeners.begin();
     969                 it != m->mListeners.end();
     970                 ++it)
     971            {
     972                it->second.obj()->shutdown();
     973            }
     974        }
     975    }
     976
    945977    AutoUninitSpan autoUninitSpan(this);
    946978    if (autoUninitSpan.uninitDone())
     
    964996    {
    965997        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     998
     999        if (m->fShutdown)
     1000            return setError(VBOX_E_INVALID_OBJECT_STATE,
     1001                            tr("This event source is already shut down"));
    9661002
    9671003        Listeners::const_iterator it = m->mListeners.find(aListener);
     
    9981034        if (it != m->mListeners.end())
    9991035        {
     1036            it->second.obj()->shutdown();
    10001037            m->mListeners.erase(it);
    10011038            // destructor removes refs from the event map
     
    10361073    do {
    10371074        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1075
     1076        if (m->fShutdown)
     1077            return setError(VBOX_E_INVALID_OBJECT_STATE,
     1078                            tr("This event source is already shut down"));
    10381079
    10391080        VBoxEventType_T evType;
     
    10831124                Listeners::iterator lit = m->mListeners.find(record.obj()->mListener);
    10841125                if (lit != m->mListeners.end())
     1126                {
     1127                    lit->second.obj()->shutdown();
    10851128                    m->mListeners.erase(lit);
     1129                }
    10861130            }
    10871131            // anything else to do with cbRc?
     
    11111155
    11121156    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1157
     1158    if (m->fShutdown)
     1159        return setError(VBOX_E_INVALID_OBJECT_STATE,
     1160                        tr("This event source is already shut down"));
    11131161
    11141162    Listeners::iterator it = m->mListeners.find(aListener);
     
    11381186
    11391187    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1188
     1189    if (m->fShutdown)
     1190        return setError(VBOX_E_INVALID_OBJECT_STATE,
     1191                        tr("This event source is already shut down"));
    11401192
    11411193    Listeners::iterator it = m->mListeners.find(aListener);
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r50544 r50545  
    803803    if (m->pEventSource)
    804804    {
    805         // we don't perform uninit() as it's possible that some pending event refers to this source
     805        // Must uninit the event source here, because it makes no sense that
     806        // it survives longer than the base object. If someone gets an event
     807        // with such an event source then that's life and it has to be dealt
     808        // with appropriately on the API client side.
     809        m->pEventSource->uninit();
    806810        unconst(m->pEventSource).setNull();
    807811    }
Note: See TracChangeset for help on using the changeset viewer.

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