>> From: Wang Yong <wang.yong...@zte.com.cn> >>
>> 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 <wang.yong...@zte.com.cn> >> Signed-off-by: Wang Guang <wang.guan...@zte.com.cn> >> --- >> 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(&iothread->stopping)) { >> aio_poll(iothread->ctx, true) >> + >> + if (atomic_read(&iothread->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(&iothread->main_loop)) { >> + g_main_loop_quit(iothread->main_loop) >> + } >> qemu_thread_join(&iothread->thread) >> return 0 >> } >> @@ -125,6 +145,7 @@ static void iothread_complete(UserCreatable *obj, Error >> **errp) >> >> qemu_mutex_init(&iothread->init_done_lock) >> qemu_cond_init(&iothread->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 <f...@redhat.com> Sorry, There's something wrong with our company's mail format. Please ignore my last reply mail. Hi Fam, Here, iothread->once can't be initialized with G_ONCE_INIT directly, must use type cast. if remove type cast , we will get an error. iothread.c: In function ‘iothread_complete’: /usr/include/glib-2.0/glib/gthread.h:101:21: error: expected expression before ‘{’ token #define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL } ^ iothread.c:149:22: note: in expansion of macro ‘G_ONCE_INIT’ iothread->once = G_ONCE_INIT Thanks > >> >> /* 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(&iothread->once, iothread_g_main_context_init, iothread) >> + >> + return iothread->worker_context >> +} >> -- >> 1.8.3.1 >> >> 原始邮件 发件人: <f...@redhat.com> 收件人:王勇10170530 抄送人: <pbonz...@redhat.com> <stefa...@redhat.com> <jasow...@redhat.com> <zhangchen.f...@cn.fujitsu.com> <zhang.zhanghaili...@huawei.com>王广10165992 <lizhij...@cn.fujitsu.com> <qemu-devel@nongnu.org> 日 期 :2017年08月31日 10:18 主 题 :Re: [PATCHv5 01/03] qemu-iothread: IOThread supports theGMainContext event loop On Tue, 08/29 15:22, Wang yong wrote: > From: Wang Yong <wang.yong...@zte.com.cn> > > 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 <wang.yong...@zte.com.cn> > Signed-off-by: Wang Guang <wang.guan...@zte.com.cn> > --- > 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(&iothread->stopping)) { > aio_poll(iothread->ctx, true) > + > + if (atomic_read(&iothread->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(&iothread->main_loop)) { > + g_main_loop_quit(iothread->main_loop) > + } > qemu_thread_join(&iothread->thread) > return 0 > } > @@ -125,6 +145,7 @@ static void iothread_complete(UserCreatable *obj, Error > **errp) > > qemu_mutex_init(&iothread->init_done_lock) > qemu_cond_init(&iothread->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 <f...@redhat.com> > > /* 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(&iothread->once, iothread_g_main_context_init, iothread) > + > + return iothread->worker_context > +} > -- > 1.8.3.1 > >