gdbusinterfaceskeleton: Use a vfunc for method dispatching

This allows libdex to use a GDBusInterfaceSkeleton subtype to dispatch
method calls in fibers.
This commit is contained in:
Sebastian Wick
2025-09-16 21:44:20 +02:00
committed by Philip Withnall
parent e2bc9c1aba
commit 3287ba22a1
2 changed files with 36 additions and 21 deletions

View File

@@ -89,7 +89,11 @@ static void skeleton_intercept_handle_method_call (GDBusConnect
GVariant *parameters, GVariant *parameters,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
gpointer user_data); 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_DEFINE_ABSTRACT_TYPE_WITH_CODE (GDBusInterfaceSkeleton, g_dbus_interface_skeleton, G_TYPE_OBJECT,
G_ADD_PRIVATE (GDBusInterfaceSkeleton) 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; gobject_class->get_property = g_dbus_interface_skeleton_get_property;
klass->g_authorize_method = g_dbus_interface_skeleton_g_authorize_method_default; 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: * GDBusInterfaceSkeleton:g-flags:
@@ -571,28 +576,21 @@ dispatch_in_thread_func (GTask *task,
} }
static void static void
g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface, g_dbus_interface_skeleton_method_dispatch_real (GDBusInterfaceSkeleton *interface,
GDBusInterfaceMethodCallFunc method_call_func, GDBusInterfaceMethodCallFunc method_call_func,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation,
GDBusInterfaceSkeletonFlags flags,
GDBusObject *object)
{ {
gboolean has_handlers; gboolean has_handlers;
gboolean has_default_class_handler; gboolean has_default_class_handler;
gboolean emit_authorized_signal; gboolean emit_authorized_signal;
gboolean run_in_thread; gboolean run_in_thread;
GDBusInterfaceSkeletonFlags flags;
GDBusObject *object;
g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface)); g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface));
g_return_if_fail (method_call_func != NULL); g_return_if_fail (method_call_func != NULL);
g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); 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 /* optimization for the common case where
* *
* a) no handler is connected and class handler is not overridden (both interface and object); and * 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; data->ref_count = 1;
task = g_task_new (interface, NULL, NULL, NULL); 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_name (task, "[gio] D-Bus interface method dispatch");
g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref); g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref);
g_task_run_in_thread (task, dispatch_in_thread_func); g_task_run_in_thread (task, dispatch_in_thread_func);
g_object_unref (task); g_object_unref (task);
} }
if (object != NULL)
g_object_unref (object);
} }
static void static void
@@ -657,9 +652,22 @@ skeleton_intercept_handle_method_call (GDBusConnection *connection,
gpointer user_data) gpointer user_data)
{ {
GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (user_data); GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (user_data);
g_dbus_interface_method_dispatch_helper (interface, GDBusInterfaceSkeletonFlags flags;
g_dbus_interface_skeleton_get_vtable (interface)->method_call, GDBusObject *object = NULL;
invocation);
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);
} }
/* ---------------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------------- */

View File

@@ -23,6 +23,7 @@
#ifndef __G_DBUS_INTERFACE_SKELETON_H__ #ifndef __G_DBUS_INTERFACE_SKELETON_H__
#define __G_DBUS_INTERFACE_SKELETON_H__ #define __G_DBUS_INTERFACE_SKELETON_H__
#include <gio/gdbusconnection.h>
#include <gio/giotypes.h> #include <gio/giotypes.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -51,6 +52,7 @@ struct _GDBusInterfaceSkeleton
* @get_vtable: Returns a #GDBusInterfaceVTable. See g_dbus_interface_skeleton_get_vtable() for details. * @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(). * @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(). * @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. * @g_authorize_method: Signal class handler for the #GDBusInterfaceSkeleton::g-authorize-method signal.
* *
* Class structure for #GDBusInterfaceSkeleton. * Class structure for #GDBusInterfaceSkeleton.
@@ -66,9 +68,14 @@ struct _GDBusInterfaceSkeletonClass
GDBusInterfaceVTable *(*get_vtable) (GDBusInterfaceSkeleton *interface_); GDBusInterfaceVTable *(*get_vtable) (GDBusInterfaceSkeleton *interface_);
GVariant *(*get_properties) (GDBusInterfaceSkeleton *interface_); GVariant *(*get_properties) (GDBusInterfaceSkeleton *interface_);
void (*flush) (GDBusInterfaceSkeleton *interface_); void (*flush) (GDBusInterfaceSkeleton *interface_);
void (*method_dispatch) (GDBusInterfaceSkeleton *interface_,
GDBusInterfaceMethodCallFunc method_call_func,
GDBusMethodInvocation *invocation,
GDBusInterfaceSkeletonFlags flags,
GDBusObject *object);
/*< private >*/ /*< private >*/
gpointer vfunc_padding[8]; gpointer vfunc_padding[7];
/*< public >*/ /*< public >*/
/* Signals */ /* Signals */