/** * \brief Trigger an event callback on a channel * * Marks the given channel as having a pending event, causing some future call * to get_next_event() to return the registered closure. * This function must only be called when enabled. * * \param chan Waitset's per-channel state * \param disp Current dispatcher pointer */ errval_t waitset_chan_trigger(struct waitset_chanstate *chan) { dispatcher_handle_t disp = disp_disable(); errval_t err = waitset_chan_trigger_disabled(chan, disp); disp_enable(disp); return err; }
/// Trigger any pending deferred events, while disabled void trigger_deferred_events_disabled(dispatcher_handle_t dh, systime_t now) { struct dispatcher_generic *dg = get_dispatcher_generic(dh); struct deferred_event *e; errval_t err; now *= SYSTIME_MULTIPLIER; for (e = dg->deferred_events; e != NULL && e->time <= now; e = e->next) { err = waitset_chan_trigger_disabled(&e->waitset_state, dh); assert(err_is_ok(err)); } dg->deferred_events = e; if (e != NULL) { e->prev = NULL; } update_wakeup_disabled(dh); }
/** * \brief Trigger send events for all LMP channels that are registered * * We don't have a good way to determine when we are likely to be able * to send on an LMP channel, so this function just trigger all such * pending events every time the dispatcher is rescheduled. * * Must be called while disabled and from dispatcher logic. */ void lmp_channels_retry_send_disabled(dispatcher_handle_t handle) { struct dispatcher_generic *dp = get_dispatcher_generic(handle); struct lmp_chan *lc, *first = dp->lmp_send_events_list, *next; errval_t err; for (lc = first; lc != NULL; lc = next) { next = lc->next; assert(next != NULL); err = waitset_chan_trigger_disabled(&lc->send_waitset, handle); assert_disabled(err_is_ok(err)); // shouldn't fail #ifndef NDEBUG lc->next = lc->prev = NULL; #endif if (next == first) { break; // wrapped } } dp->lmp_send_events_list = NULL; }