From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Daniel P . Berrange" <berrange@redhat.com>,
"Juan Quintela" <quintela@redhat.com>,
peterx@redhat.com, "Markus Armbruster" <armbru@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>
Subject: [Qemu-devel] [PATCH 09/14] qio: basic non-default context support for thread
Date: Wed, 28 Feb 2018 13:06:28 +0800 [thread overview]
Message-ID: <20180228050633.7410-10-peterx@redhat.com> (raw)
In-Reply-To: <20180228050633.7410-1-peterx@redhat.com>
qio_task_run_in_thread() allows main thread to run blocking operations
in the background. However it has an assumption on that it's always
working with the default context. This patch tries to allow the QIO task
framework to run with non-default gcontext.
Currently no functional change so far, so the QIOTasks are still always
running on main context.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
include/io/task.h | 6 ++++--
io/channel-socket.c | 9 ++++++---
io/dns-resolver.c | 3 ++-
io/task.c | 28 ++++++++++++++++++++++++++--
tests/test-io-task.c | 2 ++
5 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/include/io/task.h b/include/io/task.h
index 6021f51336..9dbe3758d7 100644
--- a/include/io/task.h
+++ b/include/io/task.h
@@ -227,15 +227,17 @@ QIOTask *qio_task_new(Object *source,
* @worker: the function to invoke in a thread
* @opaque: opaque data to pass to @worker
* @destroy: function to free @opaque
+ * @context: the context to run the complete hook
*
* Run a task in a background thread. When @worker
* returns it will call qio_task_complete() in
- * the main event thread context.
+ * the event thread context that provided.
*/
void qio_task_run_in_thread(QIOTask *task,
QIOTaskWorker worker,
gpointer opaque,
- GDestroyNotify destroy);
+ GDestroyNotify destroy,
+ GMainContext *context);
/**
* qio_task_complete:
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 563e297357..4224ce323a 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -187,7 +187,8 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
qio_task_run_in_thread(task,
qio_channel_socket_connect_worker,
addrCopy,
- (GDestroyNotify)qapi_free_SocketAddress);
+ (GDestroyNotify)qapi_free_SocketAddress,
+ NULL);
}
@@ -245,7 +246,8 @@ void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
qio_task_run_in_thread(task,
qio_channel_socket_listen_worker,
addrCopy,
- (GDestroyNotify)qapi_free_SocketAddress);
+ (GDestroyNotify)qapi_free_SocketAddress,
+ NULL);
}
@@ -321,7 +323,8 @@ void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
qio_task_run_in_thread(task,
qio_channel_socket_dgram_worker,
data,
- qio_channel_socket_dgram_worker_free);
+ qio_channel_socket_dgram_worker_free,
+ NULL);
}
diff --git a/io/dns-resolver.c b/io/dns-resolver.c
index c072d121c3..75c2ca9c4a 100644
--- a/io/dns-resolver.c
+++ b/io/dns-resolver.c
@@ -233,7 +233,8 @@ void qio_dns_resolver_lookup_async(QIODNSResolver *resolver,
qio_task_run_in_thread(task,
qio_dns_resolver_lookup_worker,
data,
- qio_dns_resolver_lookup_data_free);
+ qio_dns_resolver_lookup_data_free,
+ NULL);
}
diff --git a/io/task.c b/io/task.c
index 1a0a1c7185..204c0be286 100644
--- a/io/task.c
+++ b/io/task.c
@@ -32,6 +32,10 @@ struct QIOTask {
Error *err;
gpointer result;
GDestroyNotify destroyResult;
+
+ /* Threaded QIO task specific fields */
+ GSource *idle_source; /* The idle task to run complete routine */
+ GMainContext *context; /* The context that idle task will run with */
};
@@ -49,6 +53,7 @@ QIOTask *qio_task_new(Object *source,
task->func = func;
task->opaque = opaque;
task->destroy = destroy;
+ task->idle_source = NULL;
trace_qio_task_new(task, source, func, opaque);
@@ -66,6 +71,12 @@ static void qio_task_free(QIOTask *task)
if (task->err) {
error_free(task->err);
}
+ if (task->idle_source) {
+ g_source_unref(task->idle_source);
+ }
+ if (task->context) {
+ g_main_context_unref(task->context);
+ }
object_unref(task->source);
g_free(task);
@@ -100,6 +111,8 @@ static gboolean qio_task_thread_result(gpointer opaque)
static gpointer qio_task_thread_worker(gpointer opaque)
{
struct QIOTaskThreadData *data = opaque;
+ QIOTask *task = data->task;
+ GSource *idle;
trace_qio_task_thread_run(data->task);
data->worker(data->task, data->opaque);
@@ -110,7 +123,12 @@ static gpointer qio_task_thread_worker(gpointer opaque)
* the worker results
*/
trace_qio_task_thread_exit(data->task);
- g_idle_add(qio_task_thread_result, data);
+
+ idle = g_idle_source_new();
+ g_source_set_callback(idle, qio_task_thread_result, data, NULL);
+ g_source_attach(idle, task->context);
+ task->idle_source = idle;
+
return NULL;
}
@@ -118,11 +136,17 @@ static gpointer qio_task_thread_worker(gpointer opaque)
void qio_task_run_in_thread(QIOTask *task,
QIOTaskWorker worker,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
struct QIOTaskThreadData *data = g_new0(struct QIOTaskThreadData, 1);
QemuThread thread;
+ if (context) {
+ g_main_context_ref(context);
+ task->context = context;
+ }
+
data->task = task;
data->worker = worker;
data->opaque = opaque;
diff --git a/tests/test-io-task.c b/tests/test-io-task.c
index 141aa2c55d..bac1bb4e7a 100644
--- a/tests/test-io-task.c
+++ b/tests/test-io-task.c
@@ -187,6 +187,7 @@ static void test_task_thread_complete(void)
qio_task_run_in_thread(task,
test_task_thread_worker,
&data,
+ NULL,
NULL);
g_main_loop_run(data.loop);
@@ -228,6 +229,7 @@ static void test_task_thread_failure(void)
qio_task_run_in_thread(task,
test_task_thread_worker,
&data,
+ NULL,
NULL);
g_main_loop_run(data.loop);
--
2.14.3
next prev parent reply other threads:[~2018-02-28 5:07 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-28 5:06 [Qemu-devel] [PATCH 00/14] qio: general non-default GMainContext support Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 01/14] chardev: fix leak in tcp_chr_telnet_init_io() Peter Xu
2018-02-28 9:26 ` Daniel P. Berrangé
2018-02-28 5:06 ` [Qemu-devel] [PATCH 02/14] qio: rename qio_task_thread_result Peter Xu
2018-02-28 9:26 ` Daniel P. Berrangé
2018-02-28 5:06 ` [Qemu-devel] [PATCH 03/14] qio: introduce qio_channel_add_watch_full() Peter Xu
2018-02-28 9:08 ` Daniel P. Berrangé
2018-02-28 12:44 ` Peter Xu
2018-02-28 12:47 ` Daniel P. Berrangé
2018-02-28 13:01 ` Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 04/14] migration: let incoming side use thread context Peter Xu
2018-02-28 9:10 ` Daniel P. Berrangé
2018-03-01 4:33 ` Peter Xu
2018-02-28 17:43 ` Dr. David Alan Gilbert
2018-03-01 2:53 ` Peter Xu
2018-03-01 9:58 ` Dr. David Alan Gilbert
2018-02-28 5:06 ` [Qemu-devel] [PATCH 05/14] qio: refactor net listener source operations Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 06/14] qio: store gsources for net listeners Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 07/14] qio/chardev: update net listener gcontext Peter Xu
2018-02-28 9:25 ` Daniel P. Berrangé
2018-02-28 12:52 ` Peter Xu
2018-02-28 13:06 ` Daniel P. Berrangé
2018-02-28 5:06 ` [Qemu-devel] [PATCH 08/14] chardev: allow telnet gsource to switch gcontext Peter Xu
2018-02-28 5:06 ` Peter Xu [this message]
2018-02-28 5:06 ` [Qemu-devel] [PATCH 10/14] qio: refcount QIOTask Peter Xu
2018-02-28 9:16 ` Daniel P. Berrangé
2018-02-28 12:54 ` Peter Xu
2018-02-28 13:07 ` Daniel P. Berrangé
2018-02-28 13:15 ` Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 11/14] qio/chardev: return QIOTask when connect async Peter Xu
2018-02-28 9:20 ` Daniel P. Berrangé
2018-02-28 13:07 ` Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 12/14] qio: move QIOTaskThreadData into QIOTask Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 13/14] qio: allow threaded qiotask to switch contexts Peter Xu
2018-02-28 9:23 ` Daniel P. Berrangé
2018-02-28 13:05 ` Peter Xu
2018-02-28 13:20 ` Daniel P. Berrangé
2018-03-01 8:49 ` Peter Xu
2018-02-28 5:06 ` [Qemu-devel] [PATCH 14/14] qio/chardev: specify gcontext for TLS handshake Peter Xu
2018-02-28 13:22 ` Daniel P. Berrangé
2018-03-01 6:28 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180228050633.7410-10-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=dgilbert@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).