diff options
Diffstat (limited to 'io')
-rw-r--r-- | io/channel-socket.c | 18 | ||||
-rw-r--r-- | io/channel-tls.c | 45 | ||||
-rw-r--r-- | io/channel.c | 40 | ||||
-rw-r--r-- | io/dns-resolver.c | 3 | ||||
-rw-r--r-- | io/net-listener.c | 58 | ||||
-rw-r--r-- | io/task.c | 22 |
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); } @@ -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, |