From 73d823ac1ee0716568130407a4c164f6c145a75f Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sun, 7 Nov 2010 11:05:26 -0500 Subject: [PATCH] Implement closure-related methods for gio GSource types Also, fix up the argument ordering on GFDSourceFunc https://bugzilla.gnome.org/show_bug.cgi?id=634239 --- gio/gasynchelper.c | 59 +++++++++++++++++++++++++++++++++++++++-- gio/gasynchelper.h | 4 +-- gio/gio-marshal.list | 2 ++ gio/gsocket.c | 33 ++++++++++++++++++++++- gio/gunixinputstream.c | 4 +-- gio/gunixoutputstream.c | 4 +-- 6 files changed, 97 insertions(+), 9 deletions(-) diff --git a/gio/gasynchelper.c b/gio/gasynchelper.c index 8e2e8e61a..57590a1ec 100644 --- a/gio/gasynchelper.c +++ b/gio/gasynchelper.c @@ -78,7 +78,7 @@ fd_source_dispatch (GSource *source, g_warn_if_fail (func != NULL); - return (*func) (user_data, fd_source->pollfd.revents, fd_source->pollfd.fd); + return (*func) (fd_source->pollfd.fd, fd_source->pollfd.revents, user_data); } static void @@ -98,11 +98,66 @@ fd_source_finalize (GSource *source) g_object_unref (fd_source->cancellable); } +static gboolean +fd_source_closure_callback (int fd, + GIOCondition condition, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { { 0, }, { 0, } }; + GValue result_value = { 0, }; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶ms[0], G_TYPE_INT); + g_value_set_int (¶ms[0], fd); + + g_value_init (¶ms[1], G_TYPE_IO_CONDITION); + g_value_set_flags (¶ms[1], condition); + + g_closure_invoke (closure, &result_value, 2, params, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + + return result; +} + +static void +fd_source_closure_marshal (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + GFDSourceFunc callback; + GCClosure *cc = (GCClosure*) closure; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 0); + + callback = (GFDSourceFunc) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (g_value_get_int (param_values), + g_value_get_flags (param_values + 1), + closure->data); + + g_value_set_boolean (return_value, v_return); +} + static GSourceFuncs fd_source_funcs = { fd_source_prepare, fd_source_check, fd_source_dispatch, - fd_source_finalize + fd_source_finalize, + (GSourceFunc)fd_source_closure_callback, + (GSourceDummyMarshal)fd_source_closure_marshal, }; /* Might be called on another thread */ diff --git a/gio/gasynchelper.h b/gio/gasynchelper.h index 1e656983d..cd6d28295 100644 --- a/gio/gasynchelper.h +++ b/gio/gasynchelper.h @@ -27,9 +27,9 @@ G_BEGIN_DECLS -typedef gboolean (*GFDSourceFunc) (gpointer user_data, +typedef gboolean (*GFDSourceFunc) (int fd, GIOCondition condition, - int fd); + gpointer user_data); GSource *_g_fd_source_new (int fd, gushort events, diff --git a/gio/gio-marshal.list b/gio/gio-marshal.list index 2cd5ce200..00d16a9f7 100644 --- a/gio/gio-marshal.list +++ b/gio/gio-marshal.list @@ -25,3 +25,5 @@ VOID:POINTER,INT,STRING BOOLEAN:OBJECT INT:OBJECT VOID:INT64 +VOID:UINT64 +BOOLEAN:FLAGS diff --git a/gio/gsocket.c b/gio/gsocket.c index ad0d94033..ae45802b7 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -50,6 +50,7 @@ #include "gioerror.h" #include "gioenums.h" #include "gioerror.h" +#include "gio-marshal.h" #include "gnetworkingprivate.h" #include "gsocketaddress.h" #include "gsocketcontrolmessage.h" @@ -2493,12 +2494,42 @@ socket_source_finalize (GSource *source) } } +static gboolean +socket_source_closure_callback (GSocket *socket, + GIOCondition condition, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { { 0, }, { 0, } }; + GValue result_value = { 0, }; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶ms[0], G_TYPE_SOCKET); + g_value_set_object (¶ms[0], socket); + g_value_init (¶ms[1], G_TYPE_IO_CONDITION); + g_value_set_flags (¶ms[1], condition); + + g_closure_invoke (closure, &result_value, 2, params, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + + return result; +} + static GSourceFuncs socket_source_funcs = { socket_source_prepare, socket_source_check, socket_source_dispatch, - socket_source_finalize + socket_source_finalize, + (GSourceFunc)socket_source_closure_callback, + (GSourceDummyMarshal)_gio_marshal_BOOLEAN__FLAGS, }; static GSource * diff --git a/gio/gunixinputstream.c b/gio/gunixinputstream.c index 958d0032d..e1ee34ac1 100644 --- a/gio/gunixinputstream.c +++ b/gio/gunixinputstream.c @@ -422,9 +422,9 @@ typedef struct { } ReadAsyncData; static gboolean -read_async_cb (ReadAsyncData *data, +read_async_cb (int fd, GIOCondition condition, - int fd) + ReadAsyncData *data) { GSimpleAsyncResult *simple; GError *error = NULL; diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c index 5bc1918ad..a0acc318d 100644 --- a/gio/gunixoutputstream.c +++ b/gio/gunixoutputstream.c @@ -409,9 +409,9 @@ typedef struct { } WriteAsyncData; static gboolean -write_async_cb (WriteAsyncData *data, +write_async_cb (int fd, GIOCondition condition, - int fd) + WriteAsyncData *data) { GSimpleAsyncResult *simple; GError *error = NULL;