0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-03-14 10:27:03 +00:00

Coroutines: update coro_done to schedule an event

This commit is contained in:
Jan Maria Matejka 2018-09-13 13:21:09 +02:00
parent aa5f58ce89
commit 1e52cd6ac1
2 changed files with 19 additions and 7 deletions

View File

@ -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);

View File

@ -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");
}