[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] tests: fix iothread_join() race condition
From: |
Paolo Bonzini |
Subject: |
[PATCH] tests: fix iothread_join() race condition |
Date: |
Mon, 14 Oct 2019 12:56:27 +0200 |
This is a similar race condition to the one fixed in commit 2362a28ea1
("iothread: fix iothread_stop() race condition", 2017-12-19), which in this case
was exposed as a failure in test-aio-multithread. Here, the iothread->stopping
flag was set too soon, and the AioContext could be destroyed before the
last round of entering scheduled coroutines and bottom halves. The fix is
similar.
Reported-by: Peter Maydell <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
tests/iothread.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/tests/iothread.c b/tests/iothread.c
index 777d9eea46..1e6d3e2218 100644
--- a/tests/iothread.c
+++ b/tests/iothread.c
@@ -26,6 +26,7 @@ struct IOThread {
QemuMutex init_done_lock;
QemuCond init_done_cond; /* is thread initialization done? */
bool stopping;
+ bool running;
};
static __thread IOThread *my_iothread;
@@ -47,7 +48,7 @@ static void *iothread_run(void *opaque)
qemu_cond_signal(&iothread->init_done_cond);
qemu_mutex_unlock(&iothread->init_done_lock);
- while (!atomic_read(&iothread->stopping)) {
+ while (iothread->running) {
aio_poll(iothread->ctx, true);
}
@@ -55,10 +56,26 @@ static void *iothread_run(void *opaque)
return NULL;
}
+/* Runs in iothread_run() thread */
+static void iothread_stop_bh(void *opaque)
+{
+ IOThread *iothread = opaque;
+
+ iothread->running = false; /* stop iothread_run() */
+}
+
void iothread_join(IOThread *iothread)
{
+ /* Forbid reentering iothread_join. */
+ assert(!iothread->stopping);
iothread->stopping = true;
- aio_notify(iothread->ctx);
+
+ /*
+ * Force the loop to run once more, so that already scheduled bottom
+ * halves and coroutines are executed.
+ */
+ aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
+
qemu_thread_join(&iothread->thread);
qemu_cond_destroy(&iothread->init_done_cond);
qemu_mutex_destroy(&iothread->init_done_lock);
@@ -76,6 +93,7 @@ IOThread *iothread_new(void)
iothread, QEMU_THREAD_JOINABLE);
/* Wait for initialization to complete */
+ iothread->running = true;
qemu_mutex_lock(&iothread->init_done_lock);
while (iothread->ctx == NULL) {
qemu_cond_wait(&iothread->init_done_cond,
--
2.21.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] tests: fix iothread_join() race condition,
Paolo Bonzini <=