static void iothread_instance_finalize(Object *obj) { IOThread *iothread = IOTHREAD(obj); iothread_stop(iothread); /* * Before glib2 2.33.10, there is a glib2 bug that GSource context * pointer may not be cleared even if the context has already been * destroyed (while it should). Here let's free the AIO context * earlier to bypass that glib bug. * * We can remove this comment after the minimum supported glib2 * version boosts to 2.33.10. Before that, let's free the * GSources first before destroying any GMainContext. */ if (iothread->ctx) { aio_context_unref(iothread->ctx); iothread->ctx = NULL; } if (iothread->worker_context) { g_main_context_unref(iothread->worker_context); iothread->worker_context = NULL; } qemu_cond_destroy(&iothread->init_done_cond); qemu_mutex_destroy(&iothread->init_done_lock); }
static void iothread_instance_finalize(Object *obj) { IOThread *iothread = IOTHREAD(obj); iothread_stop(obj, NULL); qemu_cond_destroy(&iothread->init_done_cond); qemu_mutex_destroy(&iothread->init_done_lock); if (!iothread->ctx) { return; } aio_context_unref(iothread->ctx); }
static void iothread_instance_finalize(Object *obj) { IOThread *iothread = IOTHREAD(obj); if (!iothread->ctx) { return; } iothread->stopping = true; aio_notify(iothread->ctx); qemu_thread_join(&iothread->thread); qemu_cond_destroy(&iothread->init_done_cond); qemu_mutex_destroy(&iothread->init_done_lock); aio_context_unref(iothread->ctx); }
static void iothread_complete(UserCreatable *obj, Error **errp) { Error *local_error = NULL; IOThread *iothread = IOTHREAD(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) { error_propagate(errp, local_error); return; } aio_context_set_poll_params(iothread->ctx, iothread->poll_max_ns, iothread->poll_grow, iothread->poll_shrink, &local_error); if (local_error) { error_propagate(errp, local_error); aio_context_unref(iothread->ctx); iothread->ctx = NULL; return; } qemu_mutex_init(&iothread->init_done_lock); qemu_cond_init(&iothread->init_done_cond); iothread->once = (GOnce) G_ONCE_INIT; /* This assumes we are called from a thread with useful CPU affinity for us * to inherit. */ name = object_get_canonical_path_component(OBJECT(obj)); thread_name = g_strdup_printf("IO %s", name); qemu_thread_create(&iothread->thread, thread_name, iothread_run, iothread, QEMU_THREAD_JOINABLE); g_free(thread_name); g_free(name); /* Wait for initialization to complete */ qemu_mutex_lock(&iothread->init_done_lock); while (iothread->thread_id == -1) { qemu_cond_wait(&iothread->init_done_cond, &iothread->init_done_lock); } qemu_mutex_unlock(&iothread->init_done_lock); }