diff options
Diffstat (limited to 'src/VBox/Main/src-all/EventImpl.cpp')
-rw-r--r-- | src/VBox/Main/src-all/EventImpl.cpp | 420 |
1 files changed, 243 insertions, 177 deletions
diff --git a/src/VBox/Main/src-all/EventImpl.cpp b/src/VBox/Main/src-all/EventImpl.cpp index 0d19c3bdb..820f84b93 100644 --- a/src/VBox/Main/src-all/EventImpl.cpp +++ b/src/VBox/Main/src-all/EventImpl.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010-2012 Oracle Corporation + * Copyright (C) 2010-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -120,7 +120,7 @@ HRESULT VBoxEvent::init(IEventSource *aSource, VBoxEventType_T aType, BOOL aWait if (RT_FAILURE(vrc)) { - AssertFailed (); + AssertFailed(); return setError(E_FAIL, tr("Internal error (%Rrc)"), vrc); } @@ -155,19 +155,21 @@ STDMETHODIMP VBoxEvent::COMGETTER(Type)(VBoxEventType_T *aType) CheckComArgNotNull(aType); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); - // never changes till event alive, no locking? + // never changes while event alive, no locking *aType = m->mType; return S_OK; } -STDMETHODIMP VBoxEvent::COMGETTER(Source)(IEventSource* *aSource) +STDMETHODIMP VBoxEvent::COMGETTER(Source)(IEventSource **aSource) { CheckComArgOutPointerValid(aSource); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); m->mSource.queryInterfaceTo(aSource); return S_OK; @@ -178,9 +180,10 @@ STDMETHODIMP VBoxEvent::COMGETTER(Waitable)(BOOL *aWaitable) CheckComArgNotNull(aWaitable); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); - // never changes till event alive, no locking? + // never changes while event alive, no locking *aWaitable = m->mWaitable; return S_OK; } @@ -189,7 +192,8 @@ STDMETHODIMP VBoxEvent::COMGETTER(Waitable)(BOOL *aWaitable) STDMETHODIMP VBoxEvent::SetProcessed() { AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); @@ -209,7 +213,8 @@ STDMETHODIMP VBoxEvent::WaitProcessed(LONG aTimeout, BOOL *aResult) CheckComArgNotNull(aResult); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); { AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); @@ -249,8 +254,7 @@ STDMETHODIMP VBoxEvent::WaitProcessed(LONG aTimeout, BOOL *aResult) typedef std::list<Bstr> VetoList; struct VBoxVetoEvent::Data { - Data() - : + Data() : mVetoed(FALSE) {} BOOL mVetoed; @@ -281,7 +285,8 @@ HRESULT VBoxVetoEvent::init(IEventSource *aSource, VBoxEventType_T aType) HRESULT rc = S_OK; // all veto events are waitable rc = VBoxEvent::init(aSource, aType, TRUE); - if (FAILED(rc)) return rc; + if (FAILED(rc)) + return rc; m->mVetoed = FALSE; m->mVetoList.clear(); @@ -300,7 +305,8 @@ void VBoxVetoEvent::uninit() STDMETHODIMP VBoxVetoEvent::AddVeto(IN_BSTR aVeto) { AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); @@ -312,12 +318,13 @@ STDMETHODIMP VBoxVetoEvent::AddVeto(IN_BSTR aVeto) return S_OK; } -STDMETHODIMP VBoxVetoEvent::IsVetoed(BOOL * aResult) +STDMETHODIMP VBoxVetoEvent::IsVetoed(BOOL *aResult) { CheckComArgOutPointerValid(aResult); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); @@ -326,13 +333,14 @@ STDMETHODIMP VBoxVetoEvent::IsVetoed(BOOL * aResult) return S_OK; } -STDMETHODIMP VBoxVetoEvent::GetVetos(ComSafeArrayOut(BSTR, aVetos)) +STDMETHODIMP VBoxVetoEvent::GetVetos(ComSafeArrayOut(BSTR, aVetos)) { if (ComSafeArrayOutIsNull(aVetos)) return E_POINTER; AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); com::SafeArray<BSTR> vetos(m->mVetoList.size()); @@ -351,8 +359,8 @@ STDMETHODIMP VBoxVetoEvent::GetVetos(ComSafeArrayOut(BSTR, aVetos)) } static const int FirstEvent = (int)VBoxEventType_LastWildcard + 1; -static const int LastEvent = (int)VBoxEventType_Last; -static const int NumEvents = LastEvent - FirstEvent; +static const int LastEvent = (int)VBoxEventType_Last; +static const int NumEvents = LastEvent - FirstEvent; /** * Class replacing std::list and able to provide required stability @@ -367,24 +375,19 @@ public: * We have to be double linked, as structural modifications in list are delayed * till element removed, so we have to know our previous one to update its next */ - EventMapRecord* mNext; + EventMapRecord *mNext; bool mAlive; private: - EventMapRecord* mPrev; - ListenerRecord* mRef; /* must be weak reference */ + EventMapRecord *mPrev; + ListenerRecord *mRef; /* must be weak reference */ int32_t mRefCnt; public: - EventMapRecord(ListenerRecord* aRef) - : - mNext(0), - mAlive(true), - mPrev(0), - mRef(aRef), - mRefCnt(1) + EventMapRecord(ListenerRecord *aRef) : + mNext(0), mAlive(true), mPrev(0), mRef(aRef), mRefCnt(1) {} - EventMapRecord(EventMapRecord& aOther) + EventMapRecord(EventMapRecord &aOther) { mNext = aOther.mNext; mPrev = aOther.mPrev; @@ -408,7 +411,8 @@ public: void release() { - if (ASMAtomicDecS32(&mRefCnt) <= 0) delete this; + if (ASMAtomicDecS32(&mRefCnt) <= 0) + delete this; } // Called when an element is no longer needed @@ -418,7 +422,7 @@ public: release(); } - ListenerRecord* ref() + ListenerRecord *ref() { return mAlive ? mRef : 0; } @@ -473,7 +477,7 @@ public: EventMapRecord *pCur = mHead; while (pCur) { - EventMapRecord* aNext = pCur->mNext; + EventMapRecord *aNext = pCur->mNext; if (pCur->ref() == aRec) { if (pCur == mHead) @@ -495,13 +499,13 @@ public: { EventMapRecord *mCur; - iterator() - : mCur(0) + iterator() : + mCur(0) {} explicit - iterator(EventMapRecord *aCur) - : mCur(aCur) + iterator(EventMapRecord *aCur) : + mCur(aCur) { // Prevent element removal, till we're at it if (mCur) @@ -539,13 +543,13 @@ public: } bool - operator==(const EventMapList::iterator& aOther) const + operator==(const EventMapList::iterator &aOther) const { return mCur == aOther.mCur; } bool - operator!=(const EventMapList::iterator& aOther) const + operator!=(const EventMapList::iterator &aOther) const { return mCur != aOther.mCur; } @@ -563,7 +567,7 @@ public: }; typedef EventMapList EventMap[NumEvents]; -typedef std::map<IEvent*, int32_t> PendingEventsMap; +typedef std::map<IEvent *, int32_t> PendingEventsMap; typedef std::deque<ComPtr<IEvent> > PassiveQueue; class ListenerRecord @@ -571,7 +575,7 @@ class ListenerRecord private: ComPtr<IEventListener> mListener; BOOL mActive; - EventSource* mOwner; + EventSource *mOwner; RTSEMEVENT mQEvent; RTCRITSECT mcsQLock; @@ -580,24 +584,29 @@ private: uint64_t mLastRead; public: - ListenerRecord(IEventListener* aListener, - com::SafeArray<VBoxEventType_T>& aInterested, - BOOL aActive, - EventSource* aOwner); + ListenerRecord(IEventListener *aListener, + com::SafeArray<VBoxEventType_T> &aInterested, + BOOL aActive, + EventSource *aOwner); ~ListenerRecord(); - HRESULT process(IEvent* aEvent, BOOL aWaitable, PendingEventsMap::iterator& pit, AutoLockBase& alock); - HRESULT enqueue(IEvent* aEvent); - HRESULT dequeue(IEvent* *aEvent, LONG aTimeout, AutoLockBase& aAlock); - HRESULT eventProcessed(IEvent * aEvent, PendingEventsMap::iterator& pit); + HRESULT process(IEvent *aEvent, BOOL aWaitable, PendingEventsMap::iterator &pit, AutoLockBase &alock); + HRESULT enqueue(IEvent *aEvent); + HRESULT dequeue(IEvent **aEvent, LONG aTimeout, AutoLockBase &aAlock); + HRESULT eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit); + void shutdown(); + void addRef() { ASMAtomicIncS32(&mRefCnt); } + void release() { - if (ASMAtomicDecS32(&mRefCnt) <= 0) delete this; + if (ASMAtomicDecS32(&mRefCnt) <= 0) + delete this; } + BOOL isActive() { return mActive; @@ -611,15 +620,13 @@ template<typename Held> class RecordHolder { public: - RecordHolder(Held* lr) - : - held(lr) + RecordHolder(Held *lr) : + held(lr) { addref(); } - RecordHolder(const RecordHolder& that) - : - held(that.held) + RecordHolder(const RecordHolder &that) : + held(that.held) { addref(); } @@ -633,7 +640,7 @@ public: release(); } - Held* obj() + Held *obj() { return held; } @@ -644,7 +651,7 @@ public: return *this; } private: - Held* held; + Held *held; void addref() { @@ -656,7 +663,7 @@ private: if (held) held->release(); } - void safe_assign (Held *that_p) + void safe_assign(Held *that_p) { if (that_p) that_p->addRef(); @@ -665,14 +672,17 @@ private: } }; -typedef std::map<IEventListener*, RecordHolder<ListenerRecord> > Listeners; +typedef std::map<IEventListener *, RecordHolder<ListenerRecord> > Listeners; struct EventSource::Data { - Data() {} + Data() : fShutdown(false) + {} + Listeners mListeners; EventMap mEvMap; PendingEventsMap mPendingMap; + bool fShutdown; }; /** @@ -685,24 +695,22 @@ static BOOL implies(VBoxEventType_T who, VBoxEventType_T what) case VBoxEventType_Any: return TRUE; case VBoxEventType_Vetoable: - return (what == VBoxEventType_OnExtraDataCanChange) - || (what == VBoxEventType_OnCanShowWindow); + return (what == VBoxEventType_OnExtraDataCanChange) + || (what == VBoxEventType_OnCanShowWindow); case VBoxEventType_MachineEvent: - return (what == VBoxEventType_OnMachineStateChanged) - || (what == VBoxEventType_OnMachineDataChanged) - || (what == VBoxEventType_OnMachineRegistered) - || (what == VBoxEventType_OnSessionStateChanged) - || (what == VBoxEventType_OnGuestPropertyChanged); + return (what == VBoxEventType_OnMachineStateChanged) + || (what == VBoxEventType_OnMachineDataChanged) + || (what == VBoxEventType_OnMachineRegistered) + || (what == VBoxEventType_OnSessionStateChanged) + || (what == VBoxEventType_OnGuestPropertyChanged); case VBoxEventType_SnapshotEvent: - return (what == VBoxEventType_OnSnapshotTaken) - || (what == VBoxEventType_OnSnapshotDeleted) - || (what == VBoxEventType_OnSnapshotChanged) - ; + return (what == VBoxEventType_OnSnapshotTaken) + || (what == VBoxEventType_OnSnapshotDeleted) + || (what == VBoxEventType_OnSnapshotChanged) ; case VBoxEventType_InputEvent: - return (what == VBoxEventType_OnKeyboardLedsChanged) - || (what == VBoxEventType_OnMousePointerShapeChanged) - || (what == VBoxEventType_OnMouseCapabilityChanged) - ; + return (what == VBoxEventType_OnKeyboardLedsChanged) + || (what == VBoxEventType_OnMousePointerShapeChanged) + || (what == VBoxEventType_OnMouseCapabilityChanged); case VBoxEventType_Invalid: return FALSE; default: @@ -712,17 +720,14 @@ static BOOL implies(VBoxEventType_T who, VBoxEventType_T what) return who == what; } -ListenerRecord::ListenerRecord(IEventListener* aListener, - com::SafeArray<VBoxEventType_T>& aInterested, - BOOL aActive, - EventSource* aOwner) - : - mActive(aActive), - mOwner(aOwner), - mRefCnt(0) +ListenerRecord::ListenerRecord(IEventListener *aListener, + com::SafeArray<VBoxEventType_T> &aInterested, + BOOL aActive, + EventSource *aOwner) : + mActive(aActive), mOwner(aOwner), mRefCnt(0) { mListener = aListener; - EventMap* aEvMap = &aOwner->m->mEvMap; + EventMap *aEvMap = &aOwner->m->mEvMap; for (size_t i = 0; i < aInterested.size(); ++i) { @@ -740,12 +745,12 @@ ListenerRecord::ListenerRecord(IEventListener* aListener, if (!mActive) { ::RTCritSectInit(&mcsQLock); - ::RTSemEventCreate (&mQEvent); + ::RTSemEventCreate(&mQEvent); mLastRead = RTTimeMilliTS(); } else { - mQEvent =NIL_RTSEMEVENT; + mQEvent = NIL_RTSEMEVENT; RT_ZERO(mcsQLock); mLastRead = 0; } @@ -754,7 +759,7 @@ ListenerRecord::ListenerRecord(IEventListener* aListener, ListenerRecord::~ListenerRecord() { /* Remove references to us from the event map */ - EventMap* aEvMap = &mOwner->m->mEvMap; + EventMap *aEvMap = &mOwner->m->mEvMap; for (int j = FirstEvent; j < LastEvent; j++) { (*aEvMap)[j - FirstEvent].remove(this); @@ -764,7 +769,7 @@ ListenerRecord::~ListenerRecord() { // at this moment nobody could add elements to our queue, so we can safely // clean it up, otherwise there will be pending events map elements - PendingEventsMap* aPem = &mOwner->m->mPendingMap; + PendingEventsMap *aPem = &mOwner->m->mPendingMap; while (true) { ComPtr<IEvent> aEvent; @@ -786,21 +791,21 @@ ListenerRecord::~ListenerRecord() } ::RTCritSectDelete(&mcsQLock); - ::RTSemEventDestroy(mQEvent); } + shutdown(); } -HRESULT ListenerRecord::process(IEvent* aEvent, - BOOL aWaitable, - PendingEventsMap::iterator& pit, - AutoLockBase& aAlock) +HRESULT ListenerRecord::process(IEvent *aEvent, + BOOL aWaitable, + PendingEventsMap::iterator &pit, + AutoLockBase &aAlock) { if (mActive) { /* * We release lock here to allow modifying ops on EventSource inside callback. */ - HRESULT rc = S_OK; + HRESULT rc = S_OK; if (mListener) { aAlock.release(); @@ -818,7 +823,7 @@ HRESULT ListenerRecord::process(IEvent* aEvent, } -HRESULT ListenerRecord::enqueue (IEvent* aEvent) +HRESULT ListenerRecord::enqueue(IEvent *aEvent) { AssertMsg(!mActive, ("must be passive\n")); @@ -829,7 +834,7 @@ HRESULT ListenerRecord::enqueue (IEvent* aEvent) // and events keep coming, or queue is oversized we shall unregister this listener. uint64_t sinceRead = RTTimeMilliTS() - mLastRead; size_t queueSize = mQueue.size(); - if ( (queueSize > 1000) || ((queueSize > 500) && (sinceRead > 60 * 1000))) + if ((queueSize > 1000) || ((queueSize > 500) && (sinceRead > 60 * 1000))) { ::RTCritSectLeave(&mcsQLock); return E_ABORT; @@ -845,15 +850,15 @@ HRESULT ListenerRecord::enqueue (IEvent* aEvent) ::RTCritSectLeave(&mcsQLock); - // notify waiters + // notify waiters ::RTSemEventSignal(mQEvent); return S_OK; } -HRESULT ListenerRecord::dequeue (IEvent* *aEvent, - LONG aTimeout, - AutoLockBase& aAlock) +HRESULT ListenerRecord::dequeue(IEvent **aEvent, + LONG aTimeout, + AutoLockBase &aAlock) { if (mActive) return VBOX_E_INVALID_OBJECT_STATE; @@ -865,7 +870,8 @@ HRESULT ListenerRecord::dequeue (IEvent* *aEvent, mLastRead = RTTimeMilliTS(); - if (mQueue.empty()) { + if (mQueue.empty()) + { ::RTCritSectLeave(&mcsQLock); // Speed up common case if (aTimeout == 0) @@ -893,7 +899,7 @@ HRESULT ListenerRecord::dequeue (IEvent* *aEvent, return S_OK; } -HRESULT ListenerRecord::eventProcessed (IEvent* aEvent, PendingEventsMap::iterator& pit) +HRESULT ListenerRecord::eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit) { if (--pit->second == 0) { @@ -905,6 +911,16 @@ HRESULT ListenerRecord::eventProcessed (IEvent* aEvent, PendingEventsMap::iterat return S_OK; } +void ListenerRecord::shutdown() +{ + if (mQEvent != NIL_RTSEMEVENT) + { + RTSEMEVENT tmp = mQEvent; + mQEvent = NIL_RTSEMEVENT; + ::RTSemEventDestroy(tmp); + } +} + EventSource::EventSource() {} @@ -924,7 +940,7 @@ void EventSource::FinalRelease() BaseFinalRelease(); } -HRESULT EventSource::init(IUnknown *) +HRESULT EventSource::init() { HRESULT rc = S_OK; @@ -938,32 +954,58 @@ HRESULT EventSource::init(IUnknown *) 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()) return; + m->mListeners.clear(); // m->mEvMap shall be cleared at this point too by destructors, assert? } -STDMETHODIMP EventSource::RegisterListener(IEventListener * aListener, +STDMETHODIMP EventSource::RegisterListener(IEventListener *aListener, ComSafeArrayIn(VBoxEventType_T, aInterested), - BOOL aActive) + BOOL aActive) { CheckComArgNotNull(aListener); CheckComArgSafeArrayNotNull(aInterested); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); { 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); if (it != m->mListeners.end()) return setError(E_INVALIDARG, tr("This listener already registered")); - com::SafeArray<VBoxEventType_T> interested(ComSafeArrayInArg (aInterested)); + com::SafeArray<VBoxEventType_T> interested(ComSafeArrayInArg(aInterested)); RecordHolder<ListenerRecord> lrh(new ListenerRecord(aListener, interested, aActive, this)); m->mListeners.insert(Listeners::value_type(aListener, lrh)); } @@ -975,12 +1017,13 @@ STDMETHODIMP EventSource::RegisterListener(IEventListener * aListener, return S_OK; } -STDMETHODIMP EventSource::UnregisterListener(IEventListener * aListener) +STDMETHODIMP EventSource::UnregisterListener(IEventListener *aListener) { CheckComArgNotNull(aListener); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); HRESULT rc; { @@ -990,6 +1033,7 @@ STDMETHODIMP EventSource::UnregisterListener(IEventListener * aListener) if (it != m->mListeners.end()) { + it->second.obj()->shutdown(); m->mListeners.erase(it); // destructor removes refs from the event map rc = S_OK; @@ -1011,15 +1055,16 @@ STDMETHODIMP EventSource::UnregisterListener(IEventListener * aListener) return rc; } -STDMETHODIMP EventSource::FireEvent(IEvent * aEvent, - LONG aTimeout, - BOOL *aProcessed) +STDMETHODIMP EventSource::FireEvent(IEvent *aEvent, + LONG aTimeout, + BOOL *aProcessed) { CheckComArgNotNull(aEvent); CheckComArgOutPointerValid(aProcessed); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); HRESULT hrc; BOOL aWaitable = FALSE; @@ -1028,6 +1073,10 @@ STDMETHODIMP EventSource::FireEvent(IEvent * aEvent, 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; hrc = aEvent->COMGETTER(Type)(&evType); AssertComRCReturn(hrc, hrc); @@ -1074,7 +1123,10 @@ STDMETHODIMP EventSource::FireEvent(IEvent * aEvent, { 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? } @@ -1090,18 +1142,23 @@ STDMETHODIMP EventSource::FireEvent(IEvent * aEvent, } -STDMETHODIMP EventSource::GetEvent(IEventListener * aListener, - LONG aTimeout, - IEvent ** aEvent) +STDMETHODIMP EventSource::GetEvent(IEventListener *aListener, + LONG aTimeout, + IEvent **aEvent) { CheckComArgNotNull(aListener); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); 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); HRESULT rc; @@ -1117,17 +1174,22 @@ STDMETHODIMP EventSource::GetEvent(IEventListener * aListener, return rc; } -STDMETHODIMP EventSource::EventProcessed(IEventListener * aListener, - IEvent * aEvent) +STDMETHODIMP EventSource::EventProcessed(IEventListener *aListener, + IEvent *aEvent) { CheckComArgNotNull(aListener); CheckComArgNotNull(aEvent); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); 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); HRESULT rc; @@ -1136,11 +1198,11 @@ STDMETHODIMP EventSource::EventProcessed(IEventListener * aListener, if (it != m->mListeners.end()) { - ListenerRecord* aRecord = it->second.obj(); + ListenerRecord *aRecord = it->second.obj(); if (aRecord->isActive()) return setError(E_INVALIDARG, - tr("Only applicable to passive listeners")); + tr("Only applicable to passive listeners")); if (aWaitable) { @@ -1246,14 +1308,14 @@ public: BaseFinalRelease(); } - HRESULT init(IEventSource* aSource) + HRESULT init(IEventSource *aSource) { mSource = aSource; return S_OK; } // IEventListener methods - STDMETHOD(HandleEvent)(IEvent * aEvent) + STDMETHOD(HandleEvent)(IEvent *aEvent) { BOOL fProcessed = FALSE; if (mSource) @@ -1269,7 +1331,7 @@ class ATL_NO_VTABLE EventSourceAggregator : { typedef std::list <ComPtr<IEventSource> > EventSourceList; /* key is weak reference */ - typedef std::map<IEventListener*, ComPtr<IEventListener> > ProxyListenerMap; + typedef std::map<IEventListener *, ComPtr<IEventListener> > ProxyListenerMap; EventSourceList mEventSources; ProxyListenerMap mListenerProxies; @@ -1308,28 +1370,28 @@ public: HRESULT init(ComSafeArrayIn(IEventSource *, aSources)); // IEventSource methods - STDMETHOD(CreateListener)(IEventListener ** aListener); - STDMETHOD(CreateAggregator)(ComSafeArrayIn(IEventSource*, aSubordinates), - IEventSource ** aAggregator); - STDMETHOD(RegisterListener)(IEventListener * aListener, + STDMETHOD(CreateListener)(IEventListener **aListener); + STDMETHOD(CreateAggregator)(ComSafeArrayIn(IEventSource *, aSubordinates), + IEventSource **aAggregator); + STDMETHOD(RegisterListener)(IEventListener *aListener, ComSafeArrayIn(VBoxEventType_T, aInterested), - BOOL aActive); - STDMETHOD(UnregisterListener)(IEventListener * aListener); - STDMETHOD(FireEvent)(IEvent * aEvent, - LONG aTimeout, - BOOL *aProcessed); - STDMETHOD(GetEvent)(IEventListener * aListener, - LONG aTimeout, - IEvent * *aEvent); - STDMETHOD(EventProcessed)(IEventListener * aListener, - IEvent * aEvent); + BOOL aActive); + STDMETHOD(UnregisterListener)(IEventListener *aListener); + STDMETHOD(FireEvent)(IEvent *aEvent, + LONG aTimeout, + BOOL *aProcessed); + STDMETHOD(GetEvent)(IEventListener *aListener, + LONG aTimeout, + IEvent **aEvent); + STDMETHOD(EventProcessed)(IEventListener *aListener, + IEvent *aEvent); protected: - HRESULT createProxyListener(IEventListener * aListener, - IEventListener * *aProxy); - HRESULT getProxyListener (IEventListener * aListener, - IEventListener * *aProxy); - HRESULT removeProxyListener(IEventListener * aListener); + HRESULT createProxyListener(IEventListener *aListener, + IEventListener **aProxy); + HRESULT getProxyListener(IEventListener *aListener, + IEventListener **aProxy); + HRESULT removeProxyListener(IEventListener *aListener); }; #ifdef VBOX_WITH_XPCOM @@ -1348,12 +1410,13 @@ NS_IMPL_THREADSAFE_ISUPPORTS1_CI(EventSourceAggregator, IEventSource) #endif -STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener) +STDMETHODIMP EventSource::CreateListener(IEventListener **aListener) { CheckComArgOutPointerValid(aListener); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); ComObjPtr<PassiveEventListener> listener; @@ -1365,13 +1428,14 @@ STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener) } -STDMETHODIMP EventSource::CreateAggregator(ComSafeArrayIn(IEventSource*, aSubordinates), - IEventSource ** aResult) +STDMETHODIMP EventSource::CreateAggregator(ComSafeArrayIn(IEventSource *, aSubordinates), + IEventSource **aResult) { CheckComArgOutPointerValid(aResult); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); ComObjPtr<EventSourceAggregator> agg; @@ -1383,12 +1447,11 @@ STDMETHODIMP EventSource::CreateAggregator(ComSafeArrayIn(IEventSource*, aSubord if (FAILED(rc)) return rc; - agg.queryInterfaceTo(aResult); return S_OK; } -HRESULT EventSourceAggregator::init(ComSafeArrayIn(IEventSource*, aSourcesIn)) +HRESULT EventSourceAggregator::init(ComSafeArrayIn(IEventSource *, aSourcesIn)) { HRESULT rc; @@ -1398,7 +1461,7 @@ HRESULT EventSourceAggregator::init(ComSafeArrayIn(IEventSource*, aSourcesIn)) rc = mSource.createObject(); ComAssertMsgRet(SUCCEEDED(rc), ("Could not create source (%Rhrc)", rc), E_FAIL); - rc = mSource->init((IEventSource*)this); + rc = mSource->init(); ComAssertMsgRet(SUCCEEDED(rc), ("Could not init source (%Rhrc)", rc), E_FAIL); @@ -1418,26 +1481,27 @@ HRESULT EventSourceAggregator::init(ComSafeArrayIn(IEventSource*, aSourcesIn)) return rc; } -STDMETHODIMP EventSourceAggregator::CreateListener(IEventListener ** aListener) +STDMETHODIMP EventSourceAggregator::CreateListener(IEventListener **aListener) { return mSource->CreateListener(aListener); } -STDMETHODIMP EventSourceAggregator::CreateAggregator(ComSafeArrayIn(IEventSource*, aSubordinates), - IEventSource ** aResult) +STDMETHODIMP EventSourceAggregator::CreateAggregator(ComSafeArrayIn(IEventSource *, aSubordinates), + IEventSource **aResult) { return mSource->CreateAggregator(ComSafeArrayInArg(aSubordinates), aResult); } -STDMETHODIMP EventSourceAggregator::RegisterListener(IEventListener * aListener, +STDMETHODIMP EventSourceAggregator::RegisterListener(IEventListener *aListener, ComSafeArrayIn(VBoxEventType_T, aInterested), - BOOL aActive) + BOOL aActive) { CheckComArgNotNull(aListener); CheckComArgSafeArrayNotNull(aInterested); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); HRESULT rc; @@ -1462,12 +1526,13 @@ STDMETHODIMP EventSourceAggregator::RegisterListener(IEventListener * aListener, return rc; } -STDMETHODIMP EventSourceAggregator::UnregisterListener(IEventListener * aListener) +STDMETHODIMP EventSourceAggregator::UnregisterListener(IEventListener *aListener) { CheckComArgNotNull(aListener); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); HRESULT rc = S_OK; @@ -1490,19 +1555,20 @@ STDMETHODIMP EventSourceAggregator::UnregisterListener(IEventListener * aListene } -STDMETHODIMP EventSourceAggregator::FireEvent(IEvent * aEvent, - LONG aTimeout, - BOOL *aProcessed) +STDMETHODIMP EventSourceAggregator::FireEvent(IEvent *aEvent, + LONG aTimeout, + BOOL *aProcessed) { CheckComArgNotNull(aEvent); CheckComArgOutPointerValid(aProcessed); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); HRESULT rc = S_OK; AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); - /* Aggresgator event source shalln't have direct event firing, but we may + /* Aggregator event source shall not have direct event firing, but we may wish to support aggregation chains */ for (EventSourceList::const_iterator it = mEventSources.begin(); it != mEventSources.end(); ++it) @@ -1517,21 +1583,21 @@ STDMETHODIMP EventSourceAggregator::FireEvent(IEvent * aEvent, return S_OK; } -STDMETHODIMP EventSourceAggregator::GetEvent(IEventListener * aListener, - LONG aTimeout, - IEvent ** aEvent) +STDMETHODIMP EventSourceAggregator::GetEvent(IEventListener *aListener, + LONG aTimeout, + IEvent **aEvent) { return mSource->GetEvent(aListener, aTimeout, aEvent); } -STDMETHODIMP EventSourceAggregator::EventProcessed(IEventListener * aListener, - IEvent * aEvent) +STDMETHODIMP EventSourceAggregator::EventProcessed(IEventListener *aListener, + IEvent *aEvent) { return mSource->EventProcessed(aListener, aEvent); } -HRESULT EventSourceAggregator::createProxyListener(IEventListener * aListener, - IEventListener * *aProxy) +HRESULT EventSourceAggregator::createProxyListener(IEventListener *aListener, + IEventListener **aProxy) { ComObjPtr<ProxyEventListener> proxy; @@ -1554,8 +1620,8 @@ HRESULT EventSourceAggregator::createProxyListener(IEventListener * aListener, return S_OK; } -HRESULT EventSourceAggregator::getProxyListener(IEventListener * aListener, - IEventListener * *aProxy) +HRESULT EventSourceAggregator::getProxyListener(IEventListener *aListener, + IEventListener **aProxy) { ProxyListenerMap::const_iterator it = mListenerProxies.find(aListener); if (it == mListenerProxies.end()) @@ -1566,7 +1632,7 @@ HRESULT EventSourceAggregator::getProxyListener(IEventListener * aListener, return S_OK; } -HRESULT EventSourceAggregator::removeProxyListener(IEventListener * aListener) +HRESULT EventSourceAggregator::removeProxyListener(IEventListener *aListener) { ProxyListenerMap::iterator it = mListenerProxies.find(aListener); if (it == mListenerProxies.end()) |