-----BEGIN PGP SIGNATURE-----

iQEcBAABAgAGBQJZ09yuAAoJEJykq7OBq3PIMn4H/jHpYinygASL5pyQidfULpeP
 o81r03RMQOvOFNkdYHUCF5c7m37jdKVXJlikpbISTEIf4cEuy35Vs4VPob+Js5jb
 CsVmiv9C8Q+YQlQPngAfFi6UzX8smBc6GCGk4SuJZLaeAoLIlcPSvJF9ZUTTf0S5
 GFiSiQjXj97uAvWzcpy/YuEw6SM44880erNiV2LMG36PyzeP8F+Ce1NNn4VlsYtt
 0XVv4IWJZ9FlhK5v1mOTPOeaD8Pbkdju0YOc0AgqGTRzBD0goAIXA7e5ItTgHyvH
 nvUtB8TApJsT2Pvo/bYK4Iu/rkABqQaHf7Gjmg297WUSr+HJLWVhU/fMIP5R+i4=
 =Q86M
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging

# gpg: Signature made Tue 03 Oct 2017 19:53:34 BST
# gpg:                using RSA key 0x9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request:
  aio: fix assert when remove poll during destroy
  iothread: delay the context release to finalize
  iothread: export iothread_stop()
  iothread: provide helpers for internal use
  qom: provide root container for internal objs

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-10-05 12:02:21 +01:00
commit 5456c6a4ec
5 changed files with 75 additions and 11 deletions

View File

@ -1213,6 +1213,17 @@ Object *object_get_root(void);
*/
Object *object_get_objects_root(void);
/**
* object_get_internal_root:
*
* Get the container object that holds internally used object
* instances. Any object which is put into this container must not be
* user visible, and it will not be exposed in the QOM tree.
*
* Returns: the internal object container
*/
Object *object_get_internal_root(void);
/**
* object_get_canonical_path_component:
*

View File

@ -46,4 +46,13 @@ AioContext *iothread_get_aio_context(IOThread *iothread);
void iothread_stop_all(void);
GMainContext *iothread_get_g_main_context(IOThread *iothread);
/*
* Helpers used to allocate iothreads for internal use. These
* iothreads will not be seen by monitor clients when query using
* "query-iothreads".
*/
IOThread *iothread_create(const char *id, Error **errp);
void iothread_stop(IOThread *iothread);
void iothread_destroy(IOThread *iothread);
#endif /* IOTHREAD_H */

View File

@ -71,8 +71,6 @@ static void *iothread_run(void *opaque)
g_main_loop_unref(loop);
g_main_context_pop_thread_default(iothread->worker_context);
g_main_context_unref(iothread->worker_context);
iothread->worker_context = NULL;
}
}
@ -80,13 +78,10 @@ static void *iothread_run(void *opaque)
return NULL;
}
static int iothread_stop(Object *object, void *opaque)
void iothread_stop(IOThread *iothread)
{
IOThread *iothread;
iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
if (!iothread || !iothread->ctx || iothread->stopping) {
return 0;
if (!iothread->ctx || iothread->stopping) {
return;
}
iothread->stopping = true;
aio_notify(iothread->ctx);
@ -94,6 +89,17 @@ static int iothread_stop(Object *object, void *opaque)
g_main_loop_quit(iothread->main_loop);
}
qemu_thread_join(&iothread->thread);
}
static int iothread_stop_iter(Object *object, void *opaque)
{
IOThread *iothread;
iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
if (!iothread) {
return 0;
}
iothread_stop(iothread);
return 0;
}
@ -108,7 +114,11 @@ static void iothread_instance_finalize(Object *obj)
{
IOThread *iothread = IOTHREAD(obj);
iothread_stop(obj, NULL);
iothread_stop(iothread);
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);
if (!iothread->ctx) {
@ -328,7 +338,7 @@ void iothread_stop_all(void)
aio_context_release(ctx);
}
object_child_foreach(container, iothread_stop, NULL);
object_child_foreach(container, iothread_stop_iter, NULL);
}
static gpointer iothread_g_main_context_init(gpointer opaque)
@ -354,3 +364,19 @@ GMainContext *iothread_get_g_main_context(IOThread *iothread)
return iothread->worker_context;
}
IOThread *iothread_create(const char *id, Error **errp)
{
Object *obj;
obj = object_new_with_props(TYPE_IOTHREAD,
object_get_internal_root(),
id, errp, NULL);
return IOTHREAD(obj);
}
void iothread_destroy(IOThread *iothread)
{
object_unparent(OBJECT(iothread));
}

View File

@ -1370,6 +1370,17 @@ Object *object_get_objects_root(void)
return container_get(object_get_root(), "/objects");
}
Object *object_get_internal_root(void)
{
static Object *internal_root;
if (!internal_root) {
internal_root = object_new("container");
}
return internal_root;
}
static void object_get_child_property(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)

View File

@ -223,7 +223,14 @@ void aio_set_fd_handler(AioContext *ctx,
return;
}
g_source_remove_poll(&ctx->source, &node->pfd);
/* If the GSource is in the process of being destroyed then
* g_source_remove_poll() causes an assertion failure. Skip
* removal in that case, because glib cleans up its state during
* destruction anyway.
*/
if (!g_source_is_destroyed(&ctx->source)) {
g_source_remove_poll(&ctx->source, &node->pfd);
}
/* If the lock is held, just mark the node as deleted */
if (qemu_lockcnt_count(&ctx->list_lock)) {