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


Reply via email to