Ejemplo n.º 1
0
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;
        if (mListener)
        {
            aAlock.release();
            rc = mListener->HandleEvent(aEvent);
#ifdef RT_OS_WINDOWS
            Assert(rc != RPC_E_WRONG_THREAD);
#endif
            aAlock.acquire();
        }
        if (aWaitable)
            eventProcessed(aEvent, pit);
        return rc;
    }
    return enqueue(aEvent);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}