thread safety: connections and mainloops
hp at redhat.com
Tue Jul 26 06:23:07 EST 2005
On Sun, 2005-07-24 at 21:26 -0400, Colin Walters wrote:
> The next problem I ran into is how dbus_bus_get caches connections. The
> first thread sets up its mainloop with the connection, then the second
> thread gets the cached connection and tries to set the connection up
> with its mainloop (overriding the first thread), with obvious bad
> So I added dbus_bus_get_nocached. Perhaps a better approach here is to
> pass a magic cookie into dbus_bus_get; it only returns a cached bus if
> the cookie matches. The GLib bindings would use the GMainContext as the
> cookie. This would preclude sharing connections between separate
> bindings; I'm not sure if that matters much in practice. The most I
> could see is two (e.g. one for Python, and one for GLib when libhal
> internally uses the GLib bindings, or if libhal went away).
The intent of dbus_bus_get() is to share the connection (have a global
connection object), sort of like the global gdk_display in GTK. This way
every code module doesn't have to create its own socket.
Note that dbus_connection_open() _also_ returns shared connections, but
there's a dbus_connection_open_private() to avoid them.
If the thread model were one-thread-per-connection, then none of the
locking hell in dbus-connection.c would be required. The thread safety
is intended to be multiple threads accessing a single connection.
Typically you'd use multiple threads _without_ a main loop... just use
blocking IO. That's the point of threads after all.
I think a dbus_bus_get() that returns private connections is mostly
pointless, since the point of dbus_bus_get() is to have a global
connection variable. If you want a private connection, just open one and
store it in a variable somewhere.
I'm not fully answering the question of what is the right patch, but
hopefully this is useful info on the intent of the current code.
More information about the dbus