Re: [Qemu-devel] [PATCHv5 01/03] qemu-iothread: IOThread supports the GMainContext event loop
On Tue, Aug 29, 2017 at 03:22:37PM +0800, Wang yong wrote: > From: Wang Yong> > IOThread uses AioContext event loop and does not run a GMainContext. > Therefore,chardev cannot work in IOThread,such as the chardev is > used for colo-compare packets reception. > > This patch makes the IOThread run the GMainContext event loop, > chardev and IOThread can work together. > > Signed-off-by: Wang Yong > Signed-off-by: Wang Guang > --- > include/sysemu/iothread.h | 4 > iothread.c| 45 + > 2 files changed, 49 insertions(+) Reviewed-by: Stefan Hajnoczi
Re: [Qemu-devel] [PATCHv5 01/03] qemu-iothread: IOThread supports the GMainContext event loop
On Thu, 08/31 10:18, Fam Zheng wrote: > On Tue, 08/29 15:22, Wang yong wrote: > > From: Wang Yong> > > > IOThread uses AioContext event loop and does not run a GMainContext. > > Therefore,chardev cannot work in IOThread,such as the chardev is > > used for colo-compare packets reception. > > > > This patch makes the IOThread run the GMainContext event loop, > > chardev and IOThread can work together. > > > > Signed-off-by: Wang Yong > > Signed-off-by: Wang Guang > > --- > > include/sysemu/iothread.h | 4 > > iothread.c| 45 > > + > > 2 files changed, 49 insertions(+) > > > > diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h > > index e6da1a4..d2985b3 100644 > > --- a/include/sysemu/iothread.h > > +++ b/include/sysemu/iothread.h > > @@ -24,6 +24,9 @@ typedef struct { > > > > QemuThread thread; > > AioContext *ctx; > > +GMainContext *worker_context; > > +GMainLoop *main_loop; > > +GOnce once; > > QemuMutex init_done_lock; > > QemuCond init_done_cond;/* is thread initialization done? */ > > bool stopping; > > @@ -41,5 +44,6 @@ typedef struct { > > char *iothread_get_id(IOThread *iothread); > > AioContext *iothread_get_aio_context(IOThread *iothread); > > void iothread_stop_all(void); > > +GMainContext *iothread_get_g_main_context(IOThread *iothread); > > > > #endif /* IOTHREAD_H */ > > diff --git a/iothread.c b/iothread.c > > index beeb870..44c8944 100644 > > --- a/iothread.c > > +++ b/iothread.c > > @@ -57,6 +57,23 @@ static void *iothread_run(void *opaque) > > > > while (!atomic_read(>stopping)) { > > aio_poll(iothread->ctx, true); > > + > > +if (atomic_read(>worker_context)) { > > +GMainLoop *loop; > > + > > +g_main_context_push_thread_default(iothread->worker_context); > > +iothread->main_loop = > > +g_main_loop_new(iothread->worker_context, TRUE); > > +loop = iothread->main_loop; > > + > > +g_main_loop_run(iothread->main_loop); > > +iothread->main_loop = NULL; > > +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; > > +} > > } > > > > rcu_unregister_thread(); > > @@ -73,6 +90,9 @@ static int iothread_stop(Object *object, void *opaque) > > } > > iothread->stopping = true; > > aio_notify(iothread->ctx); > > +if (atomic_read(>main_loop)) { > > +g_main_loop_quit(iothread->main_loop); > > +} > > qemu_thread_join(>thread); > > return 0; > > } > > @@ -125,6 +145,7 @@ static void iothread_complete(UserCreatable *obj, Error > > **errp) > > > > qemu_mutex_init(>init_done_lock); > > qemu_cond_init(>init_done_cond); > > +iothread->once = (GOnce) G_ONCE_INIT; > > In last review I suggested removing this type cast, otherwise looks good. Drop > it and please add No, Yong is right, because this is not varialble initializer, type cast is required by C. Sorry for the noise. Fam
Re: [Qemu-devel] [PATCHv5 01/03] qemu-iothread: IOThread supports the GMainContext event loop
On Tue, 08/29 15:22, Wang yong wrote: > From: Wang Yong> > IOThread uses AioContext event loop and does not run a GMainContext. > Therefore,chardev cannot work in IOThread,such as the chardev is > used for colo-compare packets reception. > > This patch makes the IOThread run the GMainContext event loop, > chardev and IOThread can work together. > > Signed-off-by: Wang Yong > Signed-off-by: Wang Guang > --- > include/sysemu/iothread.h | 4 > iothread.c| 45 + > 2 files changed, 49 insertions(+) > > diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h > index e6da1a4..d2985b3 100644 > --- a/include/sysemu/iothread.h > +++ b/include/sysemu/iothread.h > @@ -24,6 +24,9 @@ typedef struct { > > QemuThread thread; > AioContext *ctx; > +GMainContext *worker_context; > +GMainLoop *main_loop; > +GOnce once; > QemuMutex init_done_lock; > QemuCond init_done_cond;/* is thread initialization done? */ > bool stopping; > @@ -41,5 +44,6 @@ typedef struct { > char *iothread_get_id(IOThread *iothread); > AioContext *iothread_get_aio_context(IOThread *iothread); > void iothread_stop_all(void); > +GMainContext *iothread_get_g_main_context(IOThread *iothread); > > #endif /* IOTHREAD_H */ > diff --git a/iothread.c b/iothread.c > index beeb870..44c8944 100644 > --- a/iothread.c > +++ b/iothread.c > @@ -57,6 +57,23 @@ static void *iothread_run(void *opaque) > > while (!atomic_read(>stopping)) { > aio_poll(iothread->ctx, true); > + > +if (atomic_read(>worker_context)) { > +GMainLoop *loop; > + > +g_main_context_push_thread_default(iothread->worker_context); > +iothread->main_loop = > +g_main_loop_new(iothread->worker_context, TRUE); > +loop = iothread->main_loop; > + > +g_main_loop_run(iothread->main_loop); > +iothread->main_loop = NULL; > +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; > +} > } > > rcu_unregister_thread(); > @@ -73,6 +90,9 @@ static int iothread_stop(Object *object, void *opaque) > } > iothread->stopping = true; > aio_notify(iothread->ctx); > +if (atomic_read(>main_loop)) { > +g_main_loop_quit(iothread->main_loop); > +} > qemu_thread_join(>thread); > return 0; > } > @@ -125,6 +145,7 @@ static void iothread_complete(UserCreatable *obj, Error > **errp) > > qemu_mutex_init(>init_done_lock); > qemu_cond_init(>init_done_cond); > +iothread->once = (GOnce) G_ONCE_INIT; In last review I suggested removing this type cast, otherwise looks good. Drop it and please add Reviewed-by: Fam Zheng > > /* This assumes we are called from a thread with useful CPU affinity for > us > * to inherit. > @@ -309,3 +330,27 @@ void iothread_stop_all(void) > > object_child_foreach(container, iothread_stop, NULL); > } > + > +static gpointer iothread_g_main_context_init(gpointer opaque) > +{ > +AioContext *ctx; > +IOThread *iothread = opaque; > +GSource *source; > + > +iothread->worker_context = g_main_context_new(); > + > +ctx = iothread_get_aio_context(iothread); > +source = aio_get_g_source(ctx); > +g_source_attach(source, iothread->worker_context); > +g_source_unref(source); > + > +aio_notify(iothread->ctx); > +return NULL; > +} > + > +GMainContext *iothread_get_g_main_context(IOThread *iothread) > +{ > +g_once(>once, iothread_g_main_context_init, iothread); > + > +return iothread->worker_context; > +} > -- > 1.8.3.1 > >
[Qemu-devel] [PATCHv5 01/03] qemu-iothread: IOThread supports the GMainContext event loop
From: Wang YongIOThread uses AioContext event loop and does not run a GMainContext. Therefore,chardev cannot work in IOThread,such as the chardev is used for colo-compare packets reception. This patch makes the IOThread run the GMainContext event loop, chardev and IOThread can work together. Signed-off-by: Wang Yong Signed-off-by: Wang Guang --- include/sysemu/iothread.h | 4 iothread.c| 45 + 2 files changed, 49 insertions(+) diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h index e6da1a4..d2985b3 100644 --- a/include/sysemu/iothread.h +++ b/include/sysemu/iothread.h @@ -24,6 +24,9 @@ typedef struct { QemuThread thread; AioContext *ctx; +GMainContext *worker_context; +GMainLoop *main_loop; +GOnce once; QemuMutex init_done_lock; QemuCond init_done_cond;/* is thread initialization done? */ bool stopping; @@ -41,5 +44,6 @@ typedef struct { char *iothread_get_id(IOThread *iothread); AioContext *iothread_get_aio_context(IOThread *iothread); void iothread_stop_all(void); +GMainContext *iothread_get_g_main_context(IOThread *iothread); #endif /* IOTHREAD_H */ diff --git a/iothread.c b/iothread.c index beeb870..44c8944 100644 --- a/iothread.c +++ b/iothread.c @@ -57,6 +57,23 @@ static void *iothread_run(void *opaque) while (!atomic_read(>stopping)) { aio_poll(iothread->ctx, true); + +if (atomic_read(>worker_context)) { +GMainLoop *loop; + +g_main_context_push_thread_default(iothread->worker_context); +iothread->main_loop = +g_main_loop_new(iothread->worker_context, TRUE); +loop = iothread->main_loop; + +g_main_loop_run(iothread->main_loop); +iothread->main_loop = NULL; +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; +} } rcu_unregister_thread(); @@ -73,6 +90,9 @@ static int iothread_stop(Object *object, void *opaque) } iothread->stopping = true; aio_notify(iothread->ctx); +if (atomic_read(>main_loop)) { +g_main_loop_quit(iothread->main_loop); +} qemu_thread_join(>thread); return 0; } @@ -125,6 +145,7 @@ static void iothread_complete(UserCreatable *obj, Error **errp) qemu_mutex_init(>init_done_lock); qemu_cond_init(>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. @@ -309,3 +330,27 @@ void iothread_stop_all(void) object_child_foreach(container, iothread_stop, NULL); } + +static gpointer iothread_g_main_context_init(gpointer opaque) +{ +AioContext *ctx; +IOThread *iothread = opaque; +GSource *source; + +iothread->worker_context = g_main_context_new(); + +ctx = iothread_get_aio_context(iothread); +source = aio_get_g_source(ctx); +g_source_attach(source, iothread->worker_context); +g_source_unref(source); + +aio_notify(iothread->ctx); +return NULL; +} + +GMainContext *iothread_get_g_main_context(IOThread *iothread) +{ +g_once(>once, iothread_g_main_context_init, iothread); + +return iothread->worker_context; +} -- 1.8.3.1