qemu-iothread: IOThread supports the GMainContext event loop

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.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
Wang Yong 2017-08-29 15:22:37 +08:00 committed by Jason Wang
parent 61c5f46959
commit 329163cbe6
2 changed files with 49 additions and 0 deletions

View File

@ -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 */

View File

@ -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;
/* 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;
}