GDBus: how to be notified about a non-managed object's appearence

In GDBus I can be notified about a name appearing on the bus using g_bus_watch_name_on_connection(). I can also use the GDBusObjectManager’s interfaces-added or objects-added signals to be notified about new paths under objects implementing org.freedesktop.DBus.ObjectManager.

I’m in a situation however where a name appears on a bus (let’s say: org.foobar1 and I want to create the GDBusObjectManager for /org/foobar1 but it takes a while between when the name is taken and when the top ObjectManager object appears on the bus. A workaround for that is to (re)schedule a timeout trying to create the object manager but it’s not very elegant. How can I asynchronously wait for /org/foobar to appear before trying to call g_dbus_object_manager_client_new()?

Hello, you should be able to call g_dbus_object_manager_client_new on a non-existent object. Then you can wait for it to appear by connecting to the object-added signal. Is there some error you are getting when trying this?

Yes, the error message is:

ERROR **: 09:36:15.273: failed to create the object manager: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: Object does not exist at path ?/org/foobar1?

Please note that in this case /org/foobar1 is not an object managed by an ObjectManager - it IS the object manager for objects like: /org/foobar1/xyz etc.

Oh, I think I see why that is happening now. In that case you may have to manually listen for org.freedesktop.DBus.ObjectManager.InterfacesAdded signals and wait for an object to come up. Then you will know the object manager was created.

No, this doesn’t work either, there’s simply no signal being generated at all for the top-level manager object’s creation. I monitored the bus and only see the RequestName method, and NameOwnerChanged and NameAcquired signals being generated. Except that there’s some time passing between the name being taken and the object manager being up.

I can’t be the first one to encounter this - how do people deal with it? It’s a very typical situation where you have a process waiting for some other dbus API to appear and then trying to call any method or read any property - it will fail if you do it too fast.

The usual situation is that the ObjectManager is exported to the bus by the service before it requests its well-known name.

ObjectManager was itself designed to resolve this kind of problem: it is the thing which emits signals to say when objects and interfaces are exported to or un-exported from the bus. Having another signal to say that an ObjectManager has appeared would basically be reinventing ObjectManager itself.

Without knowing the details of the service itself, my suggestion would be that the service needs to be fixed to export its ObjectManager before it requests a well-known name. That’s kind of how ObjectManager is designed to be used.

Duh! Moving the exporting code to the bus_acquired callback instead of putting it in the name_acquired handler solved the problem. Thanks a lot!

1 Like

I was going to say, another way to solve it is to expose the objects in the manager after the manager itself has been exported. However that would send many unnecessary signals, the solution from @pwithnall is much better.