aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/io/task.h7
-rw-r--r--io/channel-socket.c9
-rw-r--r--io/dns-resolver.c3
-rw-r--r--io/task.c20
-rw-r--r--tests/test-io-task.c2
5 files changed, 33 insertions, 8 deletions
diff --git a/include/io/task.h b/include/io/task.h
index 6021f51336..9e09b95b2e 100644
--- a/include/io/task.h
+++ b/include/io/task.h
@@ -227,15 +227,18 @@ 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. If %NULL, the
+ * default context will be used.
*
* 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 8359b6683a..b4d914b767 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -188,7 +188,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);
}
@@ -246,7 +247,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);
}
@@ -322,7 +324,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 8c924071c4..187f725665 100644
--- a/io/dns-resolver.c
+++ b/io/dns-resolver.c
@@ -234,7 +234,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..2886a2c1bc 100644
--- a/io/task.c
+++ b/io/task.c
@@ -77,6 +77,7 @@ struct QIOTaskThreadData {
QIOTaskWorker worker;
gpointer opaque;
GDestroyNotify destroy;
+ GMainContext *context;
};
@@ -91,6 +92,10 @@ static gboolean qio_task_thread_result(gpointer opaque)
data->destroy(data->opaque);
}
+ if (data->context) {
+ g_main_context_unref(data->context);
+ }
+
g_free(data);
return FALSE;
@@ -100,6 +105,7 @@ static gboolean qio_task_thread_result(gpointer opaque)
static gpointer qio_task_thread_worker(gpointer opaque)
{
struct QIOTaskThreadData *data = opaque;
+ GSource *idle;
trace_qio_task_thread_run(data->task);
data->worker(data->task, data->opaque);
@@ -110,7 +116,11 @@ 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, data->context);
+
return NULL;
}
@@ -118,15 +128,21 @@ 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);
+ }
+
data->task = task;
data->worker = worker;
data->opaque = opaque;
data->destroy = destroy;
+ data->context = context;
trace_qio_task_thread_start(task, worker, opaque);
qemu_thread_create(&thread,
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);