aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysemu/iothread.h3
-rw-r--r--iothread.c20
2 files changed, 17 insertions, 6 deletions
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
index 55de171..799614f 100644
--- a/include/sysemu/iothread.h
+++ b/include/sysemu/iothread.h
@@ -29,7 +29,8 @@ typedef struct {
GOnce once;
QemuMutex init_done_lock;
QemuCond init_done_cond; /* is thread initialization done? */
- bool stopping;
+ bool stopping; /* has iothread_stop() been called? */
+ bool running; /* should iothread_run() continue? */
int thread_id;
/* AioContext poll parameters */
diff --git a/iothread.c b/iothread.c
index e7b93e0..d8b6c1f 100644
--- a/iothread.c
+++ b/iothread.c
@@ -55,7 +55,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);
if (atomic_read(&iothread->worker_context)) {
@@ -78,16 +78,25 @@ 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() */
+
+ if (iothread->main_loop) {
+ g_main_loop_quit(iothread->main_loop);
+ }
+}
+
void iothread_stop(IOThread *iothread)
{
if (!iothread->ctx || iothread->stopping) {
return;
}
iothread->stopping = true;
- aio_notify(iothread->ctx);
- if (atomic_read(&iothread->main_loop)) {
- g_main_loop_quit(iothread->main_loop);
- }
+ aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
qemu_thread_join(&iothread->thread);
}
@@ -134,6 +143,7 @@ static void iothread_complete(UserCreatable *obj, Error **errp)
char *name, *thread_name;
iothread->stopping = false;
+ iothread->running = true;
iothread->thread_id = -1;
iothread->ctx = aio_context_new(&local_error);
if (!iothread->ctx) {