aboutsummaryrefslogtreecommitdiff
path: root/io
diff options
context:
space:
mode:
Diffstat (limited to 'io')
-rw-r--r--io/channel-socket.c18
-rw-r--r--io/channel-tls.c45
-rw-r--r--io/channel.c40
-rw-r--r--io/dns-resolver.c3
-rw-r--r--io/net-listener.c58
-rw-r--r--io/task.c22
6 files changed, 137 insertions, 49 deletions
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 8359b6683a..57cfb4d3a6 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -174,7 +174,8 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
SocketAddress *addr,
QIOTaskFunc callback,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
@@ -188,7 +189,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,
+ context);
}
@@ -233,7 +235,8 @@ void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
SocketAddress *addr,
QIOTaskFunc callback,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
@@ -246,7 +249,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,
+ context);
}
@@ -308,7 +312,8 @@ void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
SocketAddress *remoteAddr,
QIOTaskFunc callback,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
@@ -322,7 +327,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,
+ context);
}
diff --git a/io/channel-tls.c b/io/channel-tls.c
index 6182702dab..9628e6fa47 100644
--- a/io/channel-tls.c
+++ b/io/channel-tls.c
@@ -140,13 +140,19 @@ qio_channel_tls_new_client(QIOChannel *master,
return NULL;
}
+struct QIOChannelTLSData {
+ QIOTask *task;
+ GMainContext *context;
+};
+typedef struct QIOChannelTLSData QIOChannelTLSData;
static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
GIOCondition condition,
gpointer user_data);
static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
- QIOTask *task)
+ QIOTask *task,
+ GMainContext *context)
{
Error *err = NULL;
QCryptoTLSSessionHandshakeStatus status;
@@ -171,6 +177,15 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
qio_task_complete(task);
} else {
GIOCondition condition;
+ QIOChannelTLSData *data = g_new0(typeof(*data), 1);
+
+ data->task = task;
+ data->context = context;
+
+ if (context) {
+ g_main_context_ref(context);
+ }
+
if (status == QCRYPTO_TLS_HANDSHAKE_SENDING) {
condition = G_IO_OUT;
} else {
@@ -178,11 +193,12 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
}
trace_qio_channel_tls_handshake_pending(ioc, status);
- qio_channel_add_watch(ioc->master,
- condition,
- qio_channel_tls_handshake_io,
- task,
- NULL);
+ qio_channel_add_watch_full(ioc->master,
+ condition,
+ qio_channel_tls_handshake_io,
+ data,
+ NULL,
+ context);
}
}
@@ -191,12 +207,18 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
GIOCondition condition,
gpointer user_data)
{
- QIOTask *task = user_data;
+ QIOChannelTLSData *data = user_data;
+ QIOTask *task = data->task;
+ GMainContext *context = data->context;
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(
qio_task_get_source(task));
- qio_channel_tls_handshake_task(
- tioc, task);
+ g_free(data);
+ qio_channel_tls_handshake_task(tioc, task, context);
+
+ if (context) {
+ g_main_context_unref(context);
+ }
return FALSE;
}
@@ -204,7 +226,8 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
void qio_channel_tls_handshake(QIOChannelTLS *ioc,
QIOTaskFunc func,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task;
@@ -212,7 +235,7 @@ void qio_channel_tls_handshake(QIOChannelTLS *ioc,
func, opaque, destroy);
trace_qio_channel_tls_handshake_start(ioc);
- qio_channel_tls_handshake_task(ioc, task);
+ qio_channel_tls_handshake_task(ioc, task, context);
}
diff --git a/io/channel.c b/io/channel.c
index ec4b86de7c..8dd0684f5d 100644
--- a/io/channel.c
+++ b/io/channel.c
@@ -299,11 +299,12 @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
klass->io_set_aio_fd_handler(ioc, ctx, io_read, io_write, opaque);
}
-guint qio_channel_add_watch(QIOChannel *ioc,
- GIOCondition condition,
- QIOChannelFunc func,
- gpointer user_data,
- GDestroyNotify notify)
+guint qio_channel_add_watch_full(QIOChannel *ioc,
+ GIOCondition condition,
+ QIOChannelFunc func,
+ gpointer user_data,
+ GDestroyNotify notify,
+ GMainContext *context)
{
GSource *source;
guint id;
@@ -312,12 +313,39 @@ guint qio_channel_add_watch(QIOChannel *ioc,
g_source_set_callback(source, (GSourceFunc)func, user_data, notify);
- id = g_source_attach(source, NULL);
+ id = g_source_attach(source, context);
g_source_unref(source);
return id;
}
+guint qio_channel_add_watch(QIOChannel *ioc,
+ GIOCondition condition,
+ QIOChannelFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ return qio_channel_add_watch_full(ioc, condition, func,
+ user_data, notify, NULL);
+}
+
+GSource *qio_channel_add_watch_source(QIOChannel *ioc,
+ GIOCondition condition,
+ QIOChannelFunc func,
+ gpointer user_data,
+ GDestroyNotify notify,
+ GMainContext *context)
+{
+ GSource *source;
+ guint id;
+
+ id = qio_channel_add_watch_full(ioc, condition, func,
+ user_data, notify, context);
+ source = g_main_context_find_source_by_id(context, id);
+ g_source_ref(source);
+ return source;
+}
+
int qio_channel_shutdown(QIOChannel *ioc,
QIOChannelShutdown how,
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/net-listener.c b/io/net-listener.c
index de38dfae99..555e8acaa4 100644
--- a/io/net-listener.c
+++ b/io/net-listener.c
@@ -118,29 +118,32 @@ void qio_net_listener_add(QIONetListener *listener,
listener->sioc = g_renew(QIOChannelSocket *, listener->sioc,
listener->nsioc + 1);
- listener->io_tag = g_renew(gulong, listener->io_tag, listener->nsioc + 1);
+ listener->io_source = g_renew(typeof(listener->io_source[0]),
+ listener->io_source,
+ listener->nsioc + 1);
listener->sioc[listener->nsioc] = sioc;
- listener->io_tag[listener->nsioc] = 0;
+ listener->io_source[listener->nsioc] = NULL;
object_ref(OBJECT(sioc));
listener->connected = true;
if (listener->io_func != NULL) {
object_ref(OBJECT(listener));
- listener->io_tag[listener->nsioc] = qio_channel_add_watch(
+ listener->io_source[listener->nsioc] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[listener->nsioc]), G_IO_IN,
qio_net_listener_channel_func,
- listener, (GDestroyNotify)object_unref);
+ listener, (GDestroyNotify)object_unref, NULL);
}
listener->nsioc++;
}
-void qio_net_listener_set_client_func(QIONetListener *listener,
- QIONetListenerClientFunc func,
- gpointer data,
- GDestroyNotify notify)
+void qio_net_listener_set_client_func_full(QIONetListener *listener,
+ QIONetListenerClientFunc func,
+ gpointer data,
+ GDestroyNotify notify,
+ GMainContext *context)
{
size_t i;
@@ -152,23 +155,32 @@ void qio_net_listener_set_client_func(QIONetListener *listener,
listener->io_notify = notify;
for (i = 0; i < listener->nsioc; i++) {
- if (listener->io_tag[i]) {
- g_source_remove(listener->io_tag[i]);
- listener->io_tag[i] = 0;
+ if (listener->io_source[i]) {
+ g_source_destroy(listener->io_source[i]);
+ g_source_unref(listener->io_source[i]);
+ listener->io_source[i] = NULL;
}
}
if (listener->io_func != NULL) {
for (i = 0; i < listener->nsioc; i++) {
object_ref(OBJECT(listener));
- listener->io_tag[i] = qio_channel_add_watch(
+ listener->io_source[i] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
qio_net_listener_channel_func,
- listener, (GDestroyNotify)object_unref);
+ listener, (GDestroyNotify)object_unref, context);
}
}
}
+void qio_net_listener_set_client_func(QIONetListener *listener,
+ QIONetListenerClientFunc func,
+ gpointer data,
+ GDestroyNotify notify)
+{
+ qio_net_listener_set_client_func_full(listener, func, data,
+ notify, NULL);
+}
struct QIONetListenerClientWaitData {
QIOChannelSocket *sioc;
@@ -211,9 +223,10 @@ QIOChannelSocket *qio_net_listener_wait_client(QIONetListener *listener)
size_t i;
for (i = 0; i < listener->nsioc; i++) {
- if (listener->io_tag[i]) {
- g_source_remove(listener->io_tag[i]);
- listener->io_tag[i] = 0;
+ if (listener->io_source[i]) {
+ g_source_destroy(listener->io_source[i]);
+ g_source_unref(listener->io_source[i]);
+ listener->io_source[i] = NULL;
}
}
@@ -241,10 +254,10 @@ QIOChannelSocket *qio_net_listener_wait_client(QIONetListener *listener)
if (listener->io_func != NULL) {
for (i = 0; i < listener->nsioc; i++) {
object_ref(OBJECT(listener));
- listener->io_tag[i] = qio_channel_add_watch(
+ listener->io_source[i] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
qio_net_listener_channel_func,
- listener, (GDestroyNotify)object_unref);
+ listener, (GDestroyNotify)object_unref, NULL);
}
}
@@ -260,9 +273,10 @@ void qio_net_listener_disconnect(QIONetListener *listener)
}
for (i = 0; i < listener->nsioc; i++) {
- if (listener->io_tag[i]) {
- g_source_remove(listener->io_tag[i]);
- listener->io_tag[i] = 0;
+ if (listener->io_source[i]) {
+ g_source_destroy(listener->io_source[i]);
+ g_source_unref(listener->io_source[i]);
+ listener->io_source[i] = NULL;
}
qio_channel_close(QIO_CHANNEL(listener->sioc[i]), NULL);
}
@@ -285,7 +299,7 @@ static void qio_net_listener_finalize(Object *obj)
for (i = 0; i < listener->nsioc; i++) {
object_unref(OBJECT(listener->sioc[i]));
}
- g_free(listener->io_tag);
+ g_free(listener->io_source);
g_free(listener->sioc);
g_free(listener->name);
}
diff --git a/io/task.c b/io/task.c
index 3ce556017c..2886a2c1bc 100644
--- a/io/task.c
+++ b/io/task.c
@@ -77,10 +77,11 @@ struct QIOTaskThreadData {
QIOTaskWorker worker;
gpointer opaque;
GDestroyNotify destroy;
+ GMainContext *context;
};
-static gboolean gio_task_thread_result(gpointer opaque)
+static gboolean qio_task_thread_result(gpointer opaque)
{
struct QIOTaskThreadData *data = opaque;
@@ -91,6 +92,10 @@ static gboolean gio_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 gio_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(gio_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,