From: Jan Maria Matejka Date: Thu, 13 Sep 2018 11:21:09 +0000 (+0200) Subject: Coroutines: update coro_done to schedule an event X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e52cd6ac17c8a42bd1500f2ba58cf74d91950eb;p=thirdparty%2Fbird.git Coroutines: update coro_done to schedule an event --- diff --git a/lib/coroutine.h b/lib/coroutine.h index f3cce40c7..7b579bfe1 100644 --- a/lib/coroutine.h +++ b/lib/coroutine.h @@ -9,13 +9,15 @@ #ifndef _BIRD_COROUTINE_H_ #define _BIRD_COROUTINE_H_ +#include "lib/event.h" + // The structure is completely opaque, implemented by sysdep typedef struct coroutine coroutine; coroutine *coro_new(struct pool *pool, void (*entry_point)(void *arg), void *arg); void coro_suspend(void); void coro_resume(coroutine *c); -void coro_done(void *retval) NORET; +void coro_done(event *e) NORET; struct birdsock; int coro_sk_read(struct birdsock *s); diff --git a/sysdep/unix/coroutine.c b/sysdep/unix/coroutine.c index 8ffb81486..4d554ba37 100644 --- a/sysdep/unix/coroutine.c +++ b/sysdep/unix/coroutine.c @@ -35,6 +35,7 @@ struct coroutine { void *stack; void (*entry_point)(void *arg); void *arg; + event *ev; }; static ucontext_t *main_context; @@ -101,12 +102,14 @@ coro_new(pool *p, void (*entry_point)(void *), void *arg) } void -coro_done(void *retval) +coro_done(event *e) { ASSERT(coro_inited); ASSERT(coro_current); + if (e) + ev_schedule(e); + c->ev = e; coroutine *c = coro_current; - c->retval = retval; coro_suspend(); bug("Coroutine suspend after coro_done() should never return"); } @@ -148,6 +151,7 @@ struct coroutine { pthread_t thread; void (*entry_point)(void *arg); void *arg; + event *ev; sem_t sem; uint flags; }; @@ -163,8 +167,11 @@ coro_free(resource *r) coroutine *c = (coroutine *) r; ASSERT(coro_current != c); - c->flags |= CORO_STOP; - coro_resume(c); + if (!(c->flags & CORO_DONE)) + { + c->flags |= CORO_STOP; + coro_resume(c); + } ASSERT(c->flags & CORO_DONE); pthread_join(c->thread, NULL); @@ -241,14 +248,17 @@ coro_check_stop(void) } void -coro_done(void *retval) +coro_done(event *e) { ASSERT(coro_inited); ASSERT(coro_current); coroutine *c = coro_current; c->flags |= CORO_DONE; + c->ev = e; + if (e) + ev_schedule(e); sem_post(&coro_main_sem); - pthread_exit(retval); + pthread_exit(NULL); bug("pthread_exit should never return"); }