diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c index 086960daf..1f6ca5745 100644 --- a/gio/gdbusconnection.c +++ b/gio/gdbusconnection.c @@ -5951,7 +5951,12 @@ register_with_closures_on_method_call (GDBusConnection *connection, g_value_set_variant (¶ms[5], parameters); g_value_init (¶ms[6], G_TYPE_DBUS_METHOD_INVOCATION); - g_value_take_object (¶ms[6], g_steal_pointer (&invocation)); + /* NOTE: This is deliberately *not* g_value_take_object(). A reference to + * `invocation` is transferred in to this function, and it needs to be + * transferred onwards to the `g_dbus_method_invocation_return_*()` method + * call which must eventually happen (either in the closure function, or in + * a delayed consequence from it). Changing this will break API. */ + g_value_set_object (¶ms[6], invocation); g_closure_invoke (data->method_call_closure, NULL, G_N_ELEMENTS (params), params, NULL); @@ -6085,6 +6090,11 @@ register_with_closures_on_set_property (GDBusConnection *connection, * Version of g_dbus_connection_register_object() using closures instead of a * #GDBusInterfaceVTable for easier binding in other languages. * + * Note that the reference counting semantics of the function wrapped by + * @method_call_closure are the same as those of + * [callback@Gio.DBusInterfaceMethodCallFunc]: ownership of a reference to the + * [class@Gio.DBusMethodInvocation] is transferred to the function. + * * Returns: 0 if @error is set, otherwise a registration ID (never 0) * that can be used with g_dbus_connection_unregister_object() . * diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c index 5be560013..599df5bb5 100644 --- a/gio/tests/gdbus-export.c +++ b/gio/tests/gdbus-export.c @@ -161,23 +161,6 @@ foo_method_call (GDBusConnection *connection, } } -static void -foo_method_call_with_closure (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - /* The call below takes ownership of the invocation but ownership is not - * passed into the callback so get an additional reference here */ - g_object_ref (invocation); - - foo_method_call (connection, sender, object_path, interface_name, method_name, parameters, invocation, user_data); -} - static GVariant * foo_get_property (GDBusConnection *connection, const gchar *sender, @@ -1457,7 +1440,7 @@ test_object_registration_with_closures (void) registration_id = g_dbus_connection_register_object_with_closures (c, "/foo/boss", (GDBusInterfaceInfo *) &foo_interface_info, - g_cclosure_new (G_CALLBACK (foo_method_call_with_closure), NULL, NULL), + g_cclosure_new (G_CALLBACK (foo_method_call), NULL, NULL), g_cclosure_new (G_CALLBACK (foo_get_property), NULL, NULL), g_cclosure_new (G_CALLBACK (foo_set_property), NULL, NULL), &error);