qemu_coroutine_self() is used in several places outside of coroutine context (mostly in qcow2 tracing calls).
Ensure qemu_coroutine_self() works properly when not called from coroutine context, returning NULL in that case, and remove its coroutine_fn annotation. Signed-off-by: Alberto Faria <afa...@redhat.com> --- include/qemu/coroutine.h | 5 +++-- util/coroutine-sigaltstack.c | 4 ++-- util/coroutine-ucontext.c | 18 +++++++++--------- util/coroutine-win32.c | 9 +-------- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index e55b36f49a..0b9c8b8dac 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -95,9 +95,10 @@ void coroutine_fn qemu_coroutine_yield(void); AioContext *qemu_coroutine_get_aio_context(Coroutine *co); /** - * Get the currently executing coroutine + * Get the currently executing coroutine, or NULL if not called from coroutine + * context */ -Coroutine *coroutine_fn qemu_coroutine_self(void); +Coroutine *qemu_coroutine_self(void); /** * Return whether or not currently inside a coroutine diff --git a/util/coroutine-sigaltstack.c b/util/coroutine-sigaltstack.c index e2690c5f41..d9d90187a8 100644 --- a/util/coroutine-sigaltstack.c +++ b/util/coroutine-sigaltstack.c @@ -289,9 +289,9 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_, Coroutine *qemu_coroutine_self(void) { - CoroutineThreadState *s = coroutine_get_thread_state(); + CoroutineThreadState *s = pthread_getspecific(thread_state_key); - return s->current; + return s && s->current->caller ? s->current : NULL; } bool qemu_in_coroutine(void) diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c index ddc98fb4f8..d1dfe0dae5 100644 --- a/util/coroutine-ucontext.c +++ b/util/coroutine-ucontext.c @@ -320,18 +320,18 @@ qemu_coroutine_switch(Coroutine *from_, Coroutine *to_, Coroutine *qemu_coroutine_self(void) { Coroutine *self = get_current(); - CoroutineUContext *leaderp = get_ptr_leader(); - if (!self) { - self = &leaderp->base; - set_current(self); - } + if (self && self->caller) { #ifdef CONFIG_TSAN - if (!leaderp->tsan_co_fiber) { - leaderp->tsan_co_fiber = __tsan_get_current_fiber(); - } + CoroutineUContext *leaderp = get_ptr_leader(); + if (!leaderp->tsan_co_fiber) { + leaderp->tsan_co_fiber = __tsan_get_current_fiber(); + } #endif - return self; + return self; + } else { + return NULL; + } } bool qemu_in_coroutine(void) diff --git a/util/coroutine-win32.c b/util/coroutine-win32.c index 7db2e8f8c8..97a593da7a 100644 --- a/util/coroutine-win32.c +++ b/util/coroutine-win32.c @@ -91,14 +91,7 @@ Coroutine *qemu_coroutine_self(void) { Coroutine *current = get_current(); - if (!current) { - CoroutineWin32 *leader = get_ptr_leader(); - - current = &leader->base; - set_current(current); - leader->fiber = ConvertThreadToFiber(NULL); - } - return current; + return current && current->caller ? current : NULL; } bool qemu_in_coroutine(void) -- 2.37.3