#include "block/aio.h"
#include "block/block.h"
#include "sysemu/iothread.h"
-#include "qmp-commands.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-misc.h"
#include "qemu/error-report.h"
#include "qemu/rcu.h"
#include "qemu/main-loop.h"
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)) {
return NULL;
}
-void iothread_stop(IOThread *iothread)
+/* Runs in iothread_run() thread */
+static void iothread_stop_bh(void *opaque)
{
- if (!iothread->ctx || iothread->stopping) {
- return;
- }
- iothread->stopping = true;
- aio_notify(iothread->ctx);
- if (atomic_read(&iothread->main_loop)) {
+ IOThread *iothread = opaque;
+
+ iothread->running = false; /* stop iothread_run() */
+
+ if (iothread->main_loop) {
g_main_loop_quit(iothread->main_loop);
}
- qemu_thread_join(&iothread->thread);
}
-static int iothread_stop_iter(Object *object, void *opaque)
+void iothread_stop(IOThread *iothread)
{
- IOThread *iothread;
-
- iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
- if (!iothread) {
- return 0;
+ if (!iothread->ctx || iothread->stopping) {
+ return;
}
- iothread_stop(iothread);
- return 0;
+ iothread->stopping = true;
+ aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
+ qemu_thread_join(&iothread->thread);
}
static void iothread_instance_init(Object *obj)
char *name, *thread_name;
iothread->stopping = false;
+ iothread->running = true;
iothread->thread_id = -1;
iothread->ctx = aio_context_new(&local_error);
if (!iothread->ctx) {
return head;
}
-void iothread_stop_all(void)
-{
- Object *container = object_get_objects_root();
- BlockDriverState *bs;
- BdrvNextIterator it;
-
- for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
- AioContext *ctx = bdrv_get_aio_context(bs);
- if (ctx == qemu_get_aio_context()) {
- continue;
- }
- aio_context_acquire(ctx);
- bdrv_set_aio_context(bs, qemu_get_aio_context());
- aio_context_release(ctx);
- }
-
- object_child_foreach(container, iothread_stop_iter, NULL);
-}
-
static gpointer iothread_g_main_context_init(gpointer opaque)
{
AioContext *ctx;
{
object_unparent(OBJECT(iothread));
}
+
+/* Lookup IOThread by its id. Only finds user-created objects, not internal
+ * iothread_create() objects. */
+IOThread *iothread_by_id(const char *id)
+{
+ return IOTHREAD(object_resolve_path_type(id, TYPE_IOTHREAD, NULL));
+}