diff options
author | Dan Winship <danw@gnome.org> | 2013-07-17 18:58:18 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2013-07-17 21:41:45 -0400 |
commit | 72a7e824d65b725a5f64224ee274fe5e3d7933fc (patch) | |
tree | b7174507fba1d8d3c04ab0a7380949a7db5acb9c /gobject/gsourceclosure.c | |
parent | d06400cbaf4d3f6741a463668b2c8a56f695d124 (diff) |
gsourceclosure: fix idle/timeout/signal closures, add child watch support
And add a test for all source types.
https://bugzilla.gnome.org/show_bug.cgi?id=704267
Diffstat (limited to 'gobject/gsourceclosure.c')
-rw-r--r-- | gobject/gsourceclosure.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/gobject/gsourceclosure.c b/gobject/gsourceclosure.c index 26b89529f..a16b6c55b 100644 --- a/gobject/gsourceclosure.c +++ b/gobject/gsourceclosure.c @@ -51,6 +51,31 @@ g_io_condition_get_type (void) return etype; } +/* We need to hand-write this marshaler, since it doesn't have an + * instance object. + */ +static void +source_closure_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + GSourceFunc callback; + GCClosure *cc = (GCClosure*) closure; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 0); + + callback = (GSourceFunc) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (closure->data); + + g_value_set_boolean (return_value, v_return); +} + static gboolean io_watch_closure_callback (GIOChannel *channel, GIOCondition condition, @@ -79,6 +104,35 @@ io_watch_closure_callback (GIOChannel *channel, return result; } +static gboolean +g_child_watch_closure_callback (GPid pid, + gint status, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶ms[0], G_TYPE_ULONG); + g_value_set_ulong (¶ms[0], pid); + + g_value_init (¶ms[1], G_TYPE_INT); + g_value_set_int (¶ms[1], status); + + 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; +} + #ifdef G_OS_UNIX static gboolean g_unix_fd_source_closure_callback (int fd, @@ -138,7 +192,9 @@ closure_callback_get (gpointer cb_data, if (!closure_callback) { if (source->source_funcs == &g_io_watch_funcs) - closure_callback = (GSourceFunc)io_watch_closure_callback; + closure_callback = (GSourceFunc)io_watch_closure_callback; + else if (source->source_funcs == &g_child_watch_funcs) + closure_callback = (GSourceFunc)g_child_watch_closure_callback; #ifdef G_OS_UNIX else if (source->source_funcs == &g_unix_fd_source_funcs) closure_callback = (GSourceFunc)g_unix_fd_source_closure_callback; @@ -147,8 +203,8 @@ closure_callback_get (gpointer cb_data, #ifdef G_OS_UNIX source->source_funcs == &g_unix_signal_funcs || #endif - source->source_funcs == &g_idle_funcs) - closure_callback = source_closure_callback; + source->source_funcs == &g_idle_funcs) + closure_callback = source_closure_callback; } *func = closure_callback; @@ -191,6 +247,7 @@ g_source_set_closure (GSource *source, source->source_funcs != &g_unix_fd_source_funcs && source->source_funcs != &g_unix_signal_funcs && #endif + source->source_funcs != &g_child_watch_funcs && source->source_funcs != &g_io_watch_funcs && source->source_funcs != &g_timeout_funcs && source->source_funcs != &g_idle_funcs) @@ -210,6 +267,12 @@ g_source_set_closure (GSource *source, GClosureMarshal marshal = (GClosureMarshal)source->source_funcs->closure_marshal; if (marshal) g_closure_set_marshal (closure, marshal); + else if (source->source_funcs == &g_idle_funcs || +#ifdef G_OS_UNIX + source->source_funcs == &g_unix_signal_funcs || +#endif + source->source_funcs == &g_timeout_funcs) + g_closure_set_marshal (closure, source_closure_marshal_BOOLEAN__VOID); else g_closure_set_marshal (closure, g_cclosure_marshal_generic); } |