Add WAIT_EVENT_ONCE(event)

Waits for event if it hasn't been signaled yet. It if has, returns
without waiting, as if the event has just been signaled.
This commit is contained in:
Andrei Alexeyev 2020-04-30 21:43:57 +03:00
parent 354fa2718e
commit 31adaa7e0f
No known key found for this signature in database
GPG key ID: 363707CD4C7FE8A4
2 changed files with 32 additions and 15 deletions

View file

@ -761,12 +761,7 @@ static void coevent_add_subscriber(CoEvent *evt, CoTask *task) {
*dynarray_append_with_min_capacity(&evt->subscribers, 4) = cotask_box(task);
}
CoWaitResult cotask_wait_event(CoEvent *evt, void *arg) {
// assert(evt->unique_id > 0);
if(evt->unique_id == 0) {
return (CoWaitResult) { .event_status = CO_EVENT_CANCELED };
}
static CoWaitResult cotask_wait_event_internal(CoEvent *evt) {
CoTask *task = cotask_active();
CoTaskData *task_data = get_task_data(task);
@ -783,8 +778,28 @@ CoWaitResult cotask_wait_event(CoEvent *evt, void *arg) {
return cotask_wait_init(task_data, COTASK_WAIT_NONE);
}
CoWaitResult cotask_wait_event_or_die(CoEvent *evt, void *arg) {
CoWaitResult wr = cotask_wait_event(evt, arg);
CoWaitResult cotask_wait_event(CoEvent *evt) {
if(evt->unique_id == 0) {
return (CoWaitResult) { .event_status = CO_EVENT_CANCELED };
}
return cotask_wait_event_internal(evt);
}
CoWaitResult cotask_wait_event_once(CoEvent *evt) {
if(evt->unique_id == 0) {
return (CoWaitResult) { .event_status = CO_EVENT_CANCELED };
}
if(evt->num_signaled > 0) {
return (CoWaitResult) { .event_status = CO_EVENT_SIGNALED };
}
return cotask_wait_event_internal(evt);
}
CoWaitResult cotask_wait_event_or_die(CoEvent *evt) {
CoWaitResult wr = cotask_wait_event(evt);
if(wr.event_status == CO_EVENT_CANCELED) {
cotask_cancel(cotask_active());

View file

@ -100,8 +100,9 @@ bool cotask_cancel(CoTask *task);
void *cotask_resume(CoTask *task, void *arg);
void *cotask_yield(void *arg);
int cotask_wait(int delay);
CoWaitResult cotask_wait_event(CoEvent *evt, void *arg);
CoWaitResult cotask_wait_event_or_die(CoEvent *evt, void *arg);
CoWaitResult cotask_wait_event(CoEvent *evt);
CoWaitResult cotask_wait_event_or_die(CoEvent *evt);
CoWaitResult cotask_wait_event_once(CoEvent *evt);
CoStatus cotask_status(CoTask *task);
CoTask *cotask_active(void);
EntityInterface *cotask_bind_to_entity(CoTask *task, EntityInterface *ent) attr_returns_nonnull;
@ -404,11 +405,12 @@ DECLARE_EXTERN_TASK(_cancel_task_helper, { BoxedTask task; });
#define TASK_HOST_EVENTS(events_array) \
cotask_host_events(cotask_active(), sizeof(events_array)/sizeof(CoEvent), &((events_array)._first_event_))
#define YIELD cotask_yield(NULL)
#define WAIT(delay) cotask_wait(delay)
#define WAIT_EVENT(e) cotask_wait_event((e), NULL)
#define WAIT_EVENT_OR_DIE(e) cotask_wait_event_or_die((e), NULL)
#define STALL cotask_wait(INT_MAX)
#define YIELD cotask_yield(NULL)
#define WAIT(delay) cotask_wait(delay)
#define WAIT_EVENT(e) cotask_wait_event(e)
#define WAIT_EVENT_OR_DIE(e) cotask_wait_event_or_die(e)
#define WAIT_EVENT_ONCE(e) cotask_wait_event_once(e)
#define STALL cotask_wait(INT_MAX)
// first arg of the generated function needs to be the ent, because ENT_UNBOXED_DISPATCH_FUNCTION dispatches on first arg.
#define _cotask_emit_bindfunc(typename, ...) \