Пример #1
0
static void event_queue_runner(void *arg)
{
    struct event_queue *q = arg;
    errval_t err;

    assert(q->mode == EVENT_QUEUE_CONTINUOUS);

    thread_mutex_lock(&q->mutex);

    // dequeue the next node from the head
    struct event_queue_node *qn = next_event(q);
    if (qn == NULL) {
        // an event was cancelled while we were pending
        thread_mutex_unlock(&q->mutex);
        return;
    }

    if (q->head == NULL) {
        // queue is non-empty: trigger ourselves again
        struct event_closure self = {
            .handler = event_queue_runner,
            .arg = arg
        };
        err = waitset_chan_trigger_closure(q->waitset, &q->waitset_state, self);
        assert(err_is_ok(err)); // shouldn't fail
    }

    qn->run = true;
    thread_mutex_unlock(&q->mutex);

    // run closure
    qn->event.handler(qn->event.arg);
}
Пример #2
0
/**
 * \brief Add a new event to an event queue
 *
 * \param q Event queue
 * \param qn Storage for queue node (uninitialised)
 * \param event Event closure
 */
void event_queue_add(struct event_queue *q, struct event_queue_node *qn,
                     struct event_closure event)
{
    errval_t err;

    qn->event = event;
    qn->run = false;

    thread_mutex_lock(&q->mutex);

    // enqueue at tail
    if (q->tail == NULL) {
        assert(q->head == NULL);
        qn->next = qn->prev = NULL;
        q->head = q->tail = qn;

        // was empty: need to trigger queue runner if in continuous mode
        if (q->mode == EVENT_QUEUE_CONTINUOUS) {
            struct event_closure runner = {
                .handler = event_queue_runner,
                .arg = q
            };
            err = waitset_chan_trigger_closure(q->waitset, &q->waitset_state,
                                               runner);
            assert(err_is_ok(err)); // shouldn't fail
        }
    } else {
Пример #3
0
errval_t flounder_support_register(struct waitset *ws,
                                   struct waitset_chanstate *wc,
                                   struct event_closure ec,
                                   bool trigger_now)
{
    if (trigger_now) {
        return waitset_chan_trigger_closure(ws, wc, ec);
    } else {
        return waitset_chan_register(ws, wc, ec);
    }
}
Пример #4
0
static void span_slave_done_request(struct interdisp_binding *b)
{
    USER_PANIC("shouldn't be called");
    struct waitset_chanstate *cs = malloc(sizeof(struct waitset_chanstate));

    // Signal the default waitset of this event
    struct event_closure closure = {
        .handler = span_slave_done_handler,
        .arg = cs,
    };
    waitset_chanstate_init(cs, CHANTYPE_EVENT_QUEUE);
    errval_t err = waitset_chan_trigger_closure(get_default_waitset(), cs,
                                                closure);
    if(err_is_fail(err)) {
        USER_PANIC_ERR(err, "Triggering default waitset");
    }
}
Пример #5
0
/**
 * \brief Handled for dispatcher_initialized msg type
 *
 * Called when a recently spanned dispatcher has initialized.
 * Store it's connection object, and upcall into the registered callback
 */
static void dispatcher_initialized(struct interdisp_binding *st, genvaddr_t id)
{
    struct span_domain_state *span_domain_state = (struct span_domain_state*)(uintptr_t)id;

    // Signal the default waitset of this event
    struct event_closure closure = {
        .handler = dispatcher_initialized_handler,
        .arg = span_domain_state,
    };
    waitset_chanstate_init(&span_domain_state->initev, CHANTYPE_EVENT_QUEUE);
    errval_t err = waitset_chan_trigger_closure(get_default_waitset(),
                                                &span_domain_state->initev,
                                                closure);
    if(err_is_fail(err)) {
        USER_PANIC_ERR(err, "Triggering default waitset");
    }
}