per-user dbus

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Nov 11 07:19:53 PST 2009


On Wed, 11 Nov 2009 at 13:17:32 +0000, Simon McVittie wrote:
> On Wed, 11 Nov 2009 at 01:39:40 +0100, Lennart Poettering wrote:
> > OTOH dconf, geoclue, gvfs or telepathy don't have windows on the
> > screen and deal with data that is shared among sessions. They should
> > live on the user bus.
> 
> One problem we've seen in a real-world use of D-Bus is that if you have two
> D-Bus connections, you lose the total-ordering guarantees. As a result, if any
> of an app's functionality goes over the user bus, that whole "module" should
> use the user bus.

I didn't make my point very clearly, so I'll try to explain better...

Normally, a D-Bus API between some cooperating processes can rely on total
ordering of messages. In Telepathy we rely on this in some places.

For instance, we have a concept of Handlers (UIs, basically) that can handle
Channels (e.g. calls). A Client making a request is given a method return
with the path of an object representing the request. Later (potentially,
minutes or hours later, which is partly why we don't just use a long-running
method call) it's told to handle the Channel that resulted from the request,
by exactly the same API that would be used if the Channel had not been
requested.

The request's object path is given as an extra parameter, so UIs can relate
the channel to the request if they want to. To make this work, we guarantee
that the return from the Client's method call (with the object path) will
arrive before the HandleChannels method call (which refers to that object
path).

However, that guarantee is impossible if you read the method reply and the
method call from two different sockets, which is what one of the Maemo UIs
accidentally found itself doing (it made the method call for the request on
the starter bus, but took its well-known name on the session bus, and due
to a bug, those were not the same DBusConnection behind the scenes).

Indeed, you can't even rely on causal ordering between two different sockets -
the events happen in the right order, but are queued inside dbus-daemon, the
kernel and the applications, and the messages are popped from those queues in
an arbitrary order that depends on implementation details and even on the
kernel scheduler.

There are two ways this problem could manifest itself with a user bus:

* The user bus is the same as a particular session's bus, but libdbus
  doesn't realise that, and makes two sockets. This is solvable - libdbus
  solves it for the "starter" pseudo-bus already (possible bugs aside) -
  so it doesn't concern me much.

* The user bus is not the same as the session bus, but a "module" (e.g.
  Telepathy, viewed as a whole) is split between the two. Here, the race
  between reading the two sockets is unavoidable. The same problem exists
  between any pair of buses, like the system and session buses, but those
  have well-defined (and very different) scopes, so it's not a problem
  in practice - people don't tend to design APIs that rely on the relative
  order of system and session events.

I hope that's somewhat clearer!
    S


More information about the dbus mailing list