예제 #1
0
파일: waitset.c 프로젝트: Karamax/arrakis
/**
 * \brief Register a closure to be called when a channel is triggered
 *
 * In the Future, call the closure on a thread associated with the waitset
 * when the channel is triggered. Only one closure may be registered per
 * channel state at any one time.
 * This function must only be called when enabled.
 *
 * \param ws Waitset
 * \param chan Waitset's per-channel state
 * \param closure Event handler
 */
errval_t waitset_chan_register(struct waitset *ws, struct waitset_chanstate *chan,
                               struct event_closure closure)
{
    dispatcher_handle_t handle = disp_disable();
    errval_t err = waitset_chan_register_disabled(ws, chan, closure);
    disp_enable(handle);
    return err;
}
예제 #2
0
/**
 * \brief Register a deferred event
 *
 * \param ws Waitset
 * \param delay Delay in microseconds
 * \param closure Event closure to execute
 * \param event Storage for event metadata
 */
errval_t deferred_event_register(struct deferred_event *event,
                                 struct waitset *ws, delayus_t delay,
                                 struct event_closure closure)
{
    errval_t err;

    dispatcher_handle_t dh = disp_disable();
    err = waitset_chan_register_disabled(ws, &event->waitset_state, closure);
    if (err_is_ok(err)) {
        struct dispatcher_generic *dg = get_dispatcher_generic(dh);

        // XXX: determine absolute time for event (ignoring time since dispatch!)
        event->time = get_system_time() + delay;

        // enqueue in sorted list of pending timers
        for (struct deferred_event *e = dg->deferred_events, *p = NULL; ;
             p = e, e = e->next) {
            if (e == NULL || e->time > event->time) {
                if (p == NULL) { // insert at head
                    assert(e == dg->deferred_events);
                    event->prev = NULL;
                    event->next = e;
                    if (e != NULL) {
                        e->prev = event;
                    }
                    dg->deferred_events = event;
                } else {
                    event->next = e;
                    event->prev = p;
                    p->next = event;
                    if (e != NULL) {
                        e->prev = event;
                    }
                }
                break;
            }
        }
    }

    update_wakeup_disabled(dh);

    disp_enable(dh);

    return err;
}