qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/5] coroutines: abort if we try to enter a still-sl


From: Jeff Cody
Subject: [Qemu-devel] [PATCH 3/5] coroutines: abort if we try to enter a still-sleeping coroutine
Date: Sun, 19 Nov 2017 21:46:44 -0500

Once a coroutine is "sleeping", the timer callback will either enter the
coroutine, or schedule it for the next AioContext if using iothreads.

It is illegal to enter that coroutine while waiting for this timer
event and subsequent callback.  This patch will catch such an attempt,
and abort QEMU with an error.

Like with the previous patch, we cannot rely solely on the co->caller
check for recursive entry.  The prematurely entered coroutine may exit
with COROUTINE_TERMINATE before the timer expires, making co->caller no
longer valid.

We can clear co->sleeping in in co_sleep_cb(), because any doubly entry
attempt after point should be caught by either the co->scheduled or
co->caller checks.

Signed-off-by: Jeff Cody <address@hidden>
---
 include/qemu/coroutine_int.h | 2 ++
 util/qemu-coroutine-sleep.c  | 3 +++
 util/qemu-coroutine.c        | 5 +++++
 3 files changed, 10 insertions(+)

diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h
index 931cdc9..b071217 100644
--- a/include/qemu/coroutine_int.h
+++ b/include/qemu/coroutine_int.h
@@ -56,6 +56,8 @@ struct Coroutine {
 
     int scheduled;
 
+    int sleeping;
+
     QSIMPLEQ_ENTRY(Coroutine) co_queue_next;
     QSLIST_ENTRY(Coroutine) co_scheduled_next;
 };
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
index 9c56550..11ae95a 100644
--- a/util/qemu-coroutine-sleep.c
+++ b/util/qemu-coroutine-sleep.c
@@ -13,6 +13,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/coroutine.h"
+#include "qemu/coroutine_int.h"
 #include "qemu/timer.h"
 #include "block/aio.h"
 
@@ -25,6 +26,7 @@ static void co_sleep_cb(void *opaque)
 {
     CoSleepCB *sleep_cb = opaque;
 
+    sleep_cb->co->sleeping = 0;
     aio_co_wake(sleep_cb->co);
 }
 
@@ -34,6 +36,7 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, 
QEMUClockType type,
     CoSleepCB sleep_cb = {
         .co = qemu_coroutine_self(),
     };
+    sleep_cb.co->sleeping = 1;
     sleep_cb.ts = aio_timer_new(ctx, type, SCALE_NS, co_sleep_cb, &sleep_cb);
     timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns);
     qemu_coroutine_yield();
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
index 2edab63..1d9f93d 100644
--- a/util/qemu-coroutine.c
+++ b/util/qemu-coroutine.c
@@ -118,6 +118,11 @@ void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine 
*co)
         abort();
     }
 
+    if (co->sleeping == 1) {
+        fprintf(stderr, "Cannot enter a co-routine that is still sleeping\n");
+        abort();
+    }
+
     if (co->caller) {
         fprintf(stderr, "Co-routine re-entered recursively\n");
         abort();
-- 
2.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]