Gio.DBusObjectManagerServer.set_connection doesn't export objects
When using the PyGObject bindings, the set_connection
method of Gio.DBusObjectManagerServer
doesn't export any objects on the bus if the bus has already been acquired. When using the GIO
library directly in a C program, g_dbus_object_manager_server_set_connection
does export the objects.
I experience this on Debian unstable which has libglib2.0
2.70.4-1
and python3-gi
3.42.0-3
installed.
Example 1
Try to export an (empty) object manager after acquiring the bus.
#!/usr/bin/env python3
from gi.repository import GLib, Gio
DBUS_NAME = "org.example.Example"
DBUS_PATH = "/org/example/Example"
def on_bus_acquired(con: Gio.DBusConnection, name: str) -> None:
object_manager = Gio.DBusObjectManagerServer(object_path=DBUS_PATH)
object_manager.set_connection(con)
Gio.bus_own_name(
Gio.BusType.SESSION,
DBUS_NAME,
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT |
Gio.BusNameOwnerFlags.REPLACE,
on_bus_acquired,
)
try:
mainloop = GLib.MainLoop().run()
except KeyboardInterrupt:
mainloop = GLib.MainLoop().quit()
With this code running, the output of the following dbus-send
command is an empty node:
dbus-send --dest=org.example.Example --type=method_call --print-reply /org/example/Example org.freedesktop.DBus.Introspectable.Introspect
Example 2
Export an (empty) object manager before acquiring the bus.
#!/usr/bin/env python3
from gi.repository import GLib, Gio
DBUS_NAME = "org.example.Example"
DBUS_PATH = "/org/example/Example"
con = Gio.bus_get_sync(Gio.BusType.SESSION)
object_manager = Gio.DBusObjectManagerServer(object_path=DBUS_PATH)
object_manager.set_connection(con)
Gio.bus_own_name_on_connection(
con,
DBUS_NAME,
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT |
Gio.BusNameOwnerFlags.REPLACE,
)
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
GLib.MainLoop().quit()
This works, the output of the dbus-send command from above shows the org.freedesktop.DBus.ObjectManager
interface.
Example 3
When using the C library directly, the objects are also exported when g_dbus_object_manager_server_set_connection
is called after the bus has been acquired.
// test.c
#include <stddef.h>
#include <gio/gio.h>
static void on_bus_acquired (GDBusConnection *con,
const gchar *name,
gpointer user_data) {
GDBusObjectManagerServer* manager;
manager = g_dbus_object_manager_server_new("/org/example/Example");
g_dbus_object_manager_server_set_connection(manager, con);
}
int main() {
g_bus_own_name(G_BUS_TYPE_SESSION,
"org.example.Example",
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
G_BUS_NAME_OWNER_FLAGS_REPLACE,
on_bus_acquired,
NULL, NULL, NULL, NULL);
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run(loop);
}
Built via:
gcc -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include test.c -lgio-2.0 -lglib-2.0