Re: thread-safety of counters
Simon McVittie <simon.mcvittie-ZGY8ohtN/[email protected]>
| Newsgroups | gmane.comp.freedesktop.dbus |
|---|---|
| Organization | Collabora Ltd. |
| Message-ID | <[email protected]> |
On 23/02/15 11:23, Adrian Szyndela wrote: > Let's consider a simple test program that: > 1. creates a D-Bus connection; > 2. creates a few threads that share the connection; > 3. then, threads perform method calls over the connection. This is meant to work, but I don't recommend it. I would recommend GIO's GDBus module, particularly for multi-threaded D-Bus: its design is explicitly multi-threaded. Please be careful to distinguish between D-Bus, the protocol, and libdbus, the reference implementation of that protocol (as shipped alongside dbus-daemon in dbus.git). I consider GDBus to be a better D-Bus implementation for most purposes than libdbus. > If answer is no, then I have another question: is there any place that > describes what is thread-safe in dbus and what is not? libdbus is theoretically thread-safe, but its level of thread-safety is mostly developer folklore rather than something that is explicitly documented. I believe sharing a "large" object like a DBusConnection (perhaps also a DBusServer?) between multiple threads is *meant* to work, whereas any API call other than ref/unref on a DBusMessage requires the calling thread to "own" that message, and I'm not sure about objects of intermediate size like DBusPendingCall. One DBusConnection per thread is more likely to work than one DBusConnection shared between many threads; if you do share one DBusConnection between many threads, then restricting yourself to "dispatching" in at most one "owner" thread, and only performing blocking method calls in the other threads (as QtDBus does), is more likely to work than anything more complicated. Unfortunately, libdbus was designed to be suitable for all uses with few assumptions (e.g. any or no main-loop abstraction, any or no multi-threading design), with the predictable result that instead of doing one thing well and everything else not at all, it does lots of things but none of them very well. D-Bus reimplementations like GDBus, and libdbus wrappers like QtDBus, can do a lot better by fixing some of the details: for instance, GDBus requires the GLib main loop (which it runs in a worker thread so that calling code is not necessarily required to use it too, although that is also encouraged), and QtDBus requires the Qt main loop. > There are two messages involved, but both point to the same counter > (connection->transport->live_messages). I thought this counter was meant to be protected by one of the connection's mutexes (it has three - dispatch_mutex, io_path_mutex and mutex - because libdbus tries to be all things to all people and support an assortment of unlikely threading models). But I could be wrong... > As a conclusion, I suggest changing DBusCounter's refcount from int to > DBusAtomic, as in DBusMessage. This seems reasonable, but it would be good to know whether the counter is meant to be protected by a mutex. If so, why was that mutex not sufficient here? and if not, how do we avoid getting an incorrect value in the counter via concurrent access from different threads? -- Simon McVittie Collabora Ltd. <http://www.collabora.com/> _______________________________________________ dbus mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dbus