changeset: 76:949312711737 tag: tip user: "Daniel P. Berrange " date: Thu Oct 04 21:45:15 2007 -0400 files: src/coroutine.c description: Fix to coroutine caller state management to avoid SEGV diff -r ef58fe73ab0c -r 949312711737 src/coroutine.c --- a/src/coroutine.c Thu Oct 04 10:30:40 2007 -0300 +++ b/src/coroutine.c Thu Oct 04 21:45:15 2007 -0400 @@ -11,6 +11,7 @@ #include #include #include +#include #include "coroutine.h" int coroutine_release(struct coroutine *co) @@ -57,25 +58,23 @@ int coroutine_init(struct coroutine *co) } #if 0 -static __thread struct coroutine system; +static __thread struct coroutine leader; static __thread struct coroutine *current; #else -static struct coroutine system; +static struct coroutine leader; static struct coroutine *current; #endif struct coroutine *coroutine_self(void) { if (current == NULL) - current = &system; + current = &leader; return current; } void *coroutine_swap(struct coroutine *from, struct coroutine *to, void *arg) { int ret; - - to->caller = from; to->data = arg; current = to; ret = cc_swap(&from->cc, &to->cc); @@ -83,7 +82,7 @@ void *coroutine_swap(struct coroutine *f return from->data; else if (ret == 1) { coroutine_release(to); - current = &system; + current = &leader; to->exited = 1; return to->data; } @@ -93,12 +92,23 @@ void *coroutine_swap(struct coroutine *f void *yieldto(struct coroutine *to, void *arg) { + if (to->caller) { + fprintf(stderr, "Co-routine is re-entering itself\n"); + abort(); + } + to->caller = coroutine_self(); return coroutine_swap(coroutine_self(), to, arg); } void *yield(void *arg) { - return yieldto(coroutine_self()->caller, arg); + struct coroutine *to = coroutine_self()->caller; + if (!to) { + fprintf(stderr, "Co-routine is yielding to no one\n"); + abort(); + } + coroutine_self()->caller = NULL; + return coroutine_swap(coroutine_self(), to, arg); } /* * Local variables: