From 3287ba22a1cb800a00c6dbdde769c686dc744f49 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Tue, 16 Sep 2025 21:44:20 +0200 Subject: [PATCH] gdbusinterfaceskeleton: Use a vfunc for method dispatching This allows libdex to use a GDBusInterfaceSkeleton subtype to dispatch method calls in fibers. --- gio/gdbusinterfaceskeleton.c | 48 +++++++++++++++++++++--------------- gio/gdbusinterfaceskeleton.h | 9 ++++++- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c index e4b370702..ba4430259 100644 --- a/gio/gdbusinterfaceskeleton.c +++ b/gio/gdbusinterfaceskeleton.c @@ -89,7 +89,11 @@ static void skeleton_intercept_handle_method_call (GDBusConnect GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data); - +static void g_dbus_interface_skeleton_method_dispatch_real (GDBusInterfaceSkeleton *interface, + GDBusInterfaceMethodCallFunc method_call_func, + GDBusMethodInvocation *invocation, + GDBusInterfaceSkeletonFlags flags, + GDBusObject *object); G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GDBusInterfaceSkeleton, g_dbus_interface_skeleton, G_TYPE_OBJECT, G_ADD_PRIVATE (GDBusInterfaceSkeleton) @@ -182,6 +186,7 @@ g_dbus_interface_skeleton_class_init (GDBusInterfaceSkeletonClass *klass) gobject_class->get_property = g_dbus_interface_skeleton_get_property; klass->g_authorize_method = g_dbus_interface_skeleton_g_authorize_method_default; + klass->method_dispatch = g_dbus_interface_skeleton_method_dispatch_real; /** * GDBusInterfaceSkeleton:g-flags: @@ -571,28 +576,21 @@ dispatch_in_thread_func (GTask *task, } static void -g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface, - GDBusInterfaceMethodCallFunc method_call_func, - GDBusMethodInvocation *invocation) +g_dbus_interface_skeleton_method_dispatch_real (GDBusInterfaceSkeleton *interface, + GDBusInterfaceMethodCallFunc method_call_func, + GDBusMethodInvocation *invocation, + GDBusInterfaceSkeletonFlags flags, + GDBusObject *object) { gboolean has_handlers; gboolean has_default_class_handler; gboolean emit_authorized_signal; gboolean run_in_thread; - GDBusInterfaceSkeletonFlags flags; - GDBusObject *object; g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface)); g_return_if_fail (method_call_func != NULL); g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); - g_mutex_lock (&interface->priv->lock); - flags = interface->priv->flags; - object = interface->priv->object; - if (object != NULL) - g_object_ref (object); - g_mutex_unlock (&interface->priv->lock); - /* optimization for the common case where * * a) no handler is connected and class handler is not overridden (both interface and object); and @@ -635,15 +633,12 @@ g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface data->ref_count = 1; task = g_task_new (interface, NULL, NULL, NULL); - g_task_set_source_tag (task, g_dbus_interface_method_dispatch_helper); + g_task_set_source_tag (task, g_dbus_interface_skeleton_method_dispatch_real); g_task_set_name (task, "[gio] D-Bus interface method dispatch"); g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref); g_task_run_in_thread (task, dispatch_in_thread_func); g_object_unref (task); } - - if (object != NULL) - g_object_unref (object); } static void @@ -657,9 +652,22 @@ skeleton_intercept_handle_method_call (GDBusConnection *connection, gpointer user_data) { GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (user_data); - g_dbus_interface_method_dispatch_helper (interface, - g_dbus_interface_skeleton_get_vtable (interface)->method_call, - invocation); + GDBusInterfaceSkeletonFlags flags; + GDBusObject *object = NULL; + + g_mutex_lock (&interface->priv->lock); + flags = interface->priv->flags; + g_set_object (&object, interface->priv->object); + g_mutex_unlock (&interface->priv->lock); + + G_DBUS_INTERFACE_SKELETON_GET_CLASS (interface)->method_dispatch ( + interface, + g_dbus_interface_skeleton_get_vtable (interface)->method_call, + invocation, + flags, + object); + + g_clear_object (&object); } /* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusinterfaceskeleton.h b/gio/gdbusinterfaceskeleton.h index 5de5ff92b..51fa6bd37 100644 --- a/gio/gdbusinterfaceskeleton.h +++ b/gio/gdbusinterfaceskeleton.h @@ -23,6 +23,7 @@ #ifndef __G_DBUS_INTERFACE_SKELETON_H__ #define __G_DBUS_INTERFACE_SKELETON_H__ +#include #include G_BEGIN_DECLS @@ -51,6 +52,7 @@ struct _GDBusInterfaceSkeleton * @get_vtable: Returns a #GDBusInterfaceVTable. See g_dbus_interface_skeleton_get_vtable() for details. * @get_properties: Returns a #GVariant with all properties. See g_dbus_interface_skeleton_get_properties(). * @flush: Emits outstanding changes, if any. See g_dbus_interface_skeleton_flush(). + * @method_dispatch: Dispatches a method invocation. (Since: 2.88) * @g_authorize_method: Signal class handler for the #GDBusInterfaceSkeleton::g-authorize-method signal. * * Class structure for #GDBusInterfaceSkeleton. @@ -66,9 +68,14 @@ struct _GDBusInterfaceSkeletonClass GDBusInterfaceVTable *(*get_vtable) (GDBusInterfaceSkeleton *interface_); GVariant *(*get_properties) (GDBusInterfaceSkeleton *interface_); void (*flush) (GDBusInterfaceSkeleton *interface_); + void (*method_dispatch) (GDBusInterfaceSkeleton *interface_, + GDBusInterfaceMethodCallFunc method_call_func, + GDBusMethodInvocation *invocation, + GDBusInterfaceSkeletonFlags flags, + GDBusObject *object); /*< private >*/ - gpointer vfunc_padding[8]; + gpointer vfunc_padding[7]; /*< public >*/ /* Signals */