HRESULT ListenerRecord::dequeue(IEvent **aEvent, LONG aTimeout, AutoLockBase &aAlock) { if (mActive) return VBOX_E_INVALID_OBJECT_STATE; // retain listener record RecordHolder<ListenerRecord> holder(this); ::RTCritSectEnter(&mcsQLock); mLastRead = RTTimeMilliTS(); /* * If waiting both desired and necessary, then try grab the event * semaphore and mark it busy. If it's NIL we've been shut down already. */ if (aTimeout != 0 && mQueue.empty()) { RTSEMEVENT hEvt = mQEvent; if (hEvt != NIL_RTSEMEVENT) { ASMAtomicIncS32(&mQEventBusyCnt); ::RTCritSectLeave(&mcsQLock); // release lock while waiting, listener will not go away due to above holder aAlock.release(); ::RTSemEventWait(hEvt, aTimeout); ASMAtomicDecS32(&mQEventBusyCnt); // reacquire lock aAlock.acquire(); ::RTCritSectEnter(&mcsQLock); } } if (mQueue.empty()) *aEvent = NULL; else { mQueue.front().queryInterfaceTo(aEvent); mQueue.pop_front(); } ::RTCritSectLeave(&mcsQLock); return S_OK; }
HRESULT ListenerRecord::dequeue (IEvent* *aEvent, LONG aTimeout, AutoLockBase& aAlock) { if (mActive) return VBOX_E_INVALID_OBJECT_STATE; // retain listener record RecordHolder<ListenerRecord> holder(this); ::RTCritSectEnter(&mcsQLock); mLastRead = RTTimeMilliTS(); if (mQueue.empty()) { ::RTCritSectLeave(&mcsQLock); // Speed up common case if (aTimeout == 0) { *aEvent = NULL; return S_OK; } // release lock while waiting, listener will not go away due to above holder aAlock.release(); ::RTSemEventWait(mQEvent, aTimeout); // reacquire lock aAlock.acquire(); ::RTCritSectEnter(&mcsQLock); } if (mQueue.empty()) { *aEvent = NULL; } else { mQueue.front().queryInterfaceTo(aEvent); mQueue.pop_front(); } ::RTCritSectLeave(&mcsQLock); return S_OK; }