#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);
void *stack;
void (*entry_point)(void *arg);
void *arg;
+ event *ev;
};
static ucontext_t *main_context;
}
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");
}
pthread_t thread;
void (*entry_point)(void *arg);
void *arg;
+ event *ev;
sem_t sem;
uint flags;
};
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);
}
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");
}