Draft: gdbus-codegen: Support dex future proxy method calls and dex fiber skeleton method invocation
Adds support for dex in the gdbus codegen. The changes are limited to the codegen, don't add a dependency on libdex, and are only in effect when --c-generate-futures is passed.
This adds two things in particular:
- Dbus proxys get a new variant of calling methods:
${interface}_call_${method}_futurewhich returns aDexFuturethat resolves or rejects at some point - Dbus skeleton interfaces get a new variant of handling method calls: if the new
fiber_${method}vfunc is set, method calls get dispatched in aDexFiberinstead of the signal/vfunc
To see how this can be used, and the boilerplate it replaces, see https://gitlab.gnome.org/swick/gdbus-libdex-codegen-test.
The gist of it:
static DexFuture *
do_some_dbus_stuff (G_GNUC_UNUSED gpointer user_data)
{
g_autoptr(GDBusConnection) connection = NULL;
g_autoptr(DbusSystemd1Manager) manager = NULL;
g_autoptr(DbusSystemd1ManagerGetDefaultTargetResult) default_target = NULL;
g_autoptr(GError) error = NULL;
connection = dex_await_object (dex_bus_get (G_BUS_TYPE_SESSION), &error);
if (!connection)
return dex_future_new_for_error (g_steal_pointer (&error));
manager = dex_await_object (dbus_systemd1_manager_proxy_new_future (connection,
G_DBUS_PROXY_FLAGS_NONE,
"org.example.test",
"/org/example/test"),
&error);
if (!manager)
return dex_future_new_for_error (g_steal_pointer (&error));
default_target = dex_await_boxed (dbus_systemd1_manager_call_get_default_target_future (manager),
&error);
if (!default_target)
return dex_future_new_for_error (g_steal_pointer (&error));
return dex_future_new_for_string (default_target->name);
}
struct _Systemd1Manager
{
DbusSystemd1ManagerSkeleton parent_instance;
};
struct Systemd1ManagerClass
{
DbusSystemd1ManagerSkeletonClass parent_class;
};
static void dbus_systemd1_manager_iface_init (DbusSystemd1ManagerIface *iface);
#define SYSTEMD1_TYPE_MANAGER (systemd1_manager_get_type ())
G_DECLARE_FINAL_TYPE (Systemd1Manager,
systemd1_manager,
Systemd1, MANAGER,
DbusSystemd1ManagerSkeleton)
G_DEFINE_TYPE_WITH_CODE (Systemd1Manager,
systemd1_manager,
DBUS_SYSTEMD1_TYPE_MANAGER_SKELETON,
G_IMPLEMENT_INTERFACE (DBUS_SYSTEMD1_TYPE_MANAGER,
dbus_systemd1_manager_iface_init));
static GMainLoop *main_loop;
static gboolean
handle_get_default_target (DbusSystemd1Manager *object,
GDBusMethodInvocation *invocation)
{
dex_await (dex_timeout_new_seconds (1), NULL);
dbus_systemd1_manager_complete_get_default_target (object,
invocation,
"test.target");
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
static void
dbus_systemd1_manager_iface_init (DbusSystemd1ManagerIface *iface)
{
iface->method_invocations_in_fiber = TRUE;
iface->handle_get_default_target = handle_get_default_target;
}
static void
systemd1_manager_init (Systemd1Manager *manager)
{
}
static void
systemd1_manager_class_init (Systemd1ManagerClass *klass)
{
}
ToDo before un-drafting:
-
fix the failing codegen test -
run some test with --c-generate-futuresto ensure no regressions -
add some tests with libdex
Enhancements:
-
cancel fibers on dispose
Edited by Sebastian Wick