示例#1
0
/*
    Append a new event. Must be locked when called.
 */
static void queueEvent(MprEvent *prior, MprEvent *event)
{
    assert(prior);
    assert(event);
    assert(prior->next);

    if (event->next) {
        mprDequeueEvent(event);
    }
    event->prev = prior;
    event->next = prior->next;
    prior->next->prev = event;
    prior->next = event;
}
示例#2
0
PUBLIC void mprRemoveEvent(MprEvent *event)
{
    MprEventService     *es;
    MprDispatcher       *dispatcher;

    dispatcher = event->dispatcher;
    if (dispatcher) {
        es = dispatcher->service;
        lock(es);
        if (event->next && !(event->flags & MPR_EVENT_RUNNING)) {
            mprDequeueEvent(event);
        }
        event->dispatcher = 0;
        event->flags &= ~MPR_EVENT_CONTINUOUS;
        if (event->due == es->willAwake && dispatcher->eventQ->next != dispatcher->eventQ) {
            mprScheduleDispatcher(dispatcher);
        }
        unlock(es);
    }
}
示例#3
0
/*
    Run events for a dispatcher
 */
static int dispatchEvents(MprDispatcher *dispatcher)
{
    MprEventService     *es;
    MprEvent            *event;
    MprOsThread         priorOwner;
    int                 count;

    if (mprIsStopped()) {
        return 0;
    }
    assert(isRunning(dispatcher));
    es = dispatcher->service;

    priorOwner = dispatcher->owner;
    assert(priorOwner == 0 || priorOwner == mprGetCurrentOsThread());

    dispatcher->owner = mprGetCurrentOsThread();

    /*
        Events are removed from the dispatcher queue and put onto the currentQ. This is so they will be marked for GC.
        If the callback calls mprRemoveEvent, it will not remove from the currentQ. If it was a continuous event,
        mprRemoveEvent will clear the continuous flag.

        OPT - this could all be simpler if dispatchEvents was never called recursively. Then a currentQ would not be needed,
        and neither would a running flag. See mprRemoveEvent().
     */
    for (count = 0; (event = mprGetNextEvent(dispatcher)) != 0; count++) {
        assert(!(event->flags & MPR_EVENT_RUNNING));
        event->flags |= MPR_EVENT_RUNNING;

        assert(event->proc);
        mprAtomicAdd64(&dispatcher->mark, 1);

        (event->proc)(event->data, event);
        if (event->cond) {
            mprSignalCond(event->cond);
        }

        if (dispatcher->flags & MPR_DISPATCHER_DESTROYED) {
            break;
        }
        event->flags &= ~MPR_EVENT_RUNNING;

        lock(es);
        if (event->flags & MPR_EVENT_CONTINUOUS) {
            /*
                Reschedule if continuous
             */
            if (event->next) {
                mprDequeueEvent(event);
            }
            event->timestamp = dispatcher->service->now;
            event->due = event->timestamp + (event->period ? event->period : 1);
            mprQueueEvent(dispatcher, event);
        } else {
            mprDequeueEvent(event);
        }
        es->eventCount++;
        unlock(es);
        assert(dispatcher->owner == mprGetCurrentOsThread());
    }
    dispatcher->owner = priorOwner;
    return count;
}