Re: libdbus or gio dbus for multi-threaded service ?

"Daniel P. Berrange" <dan-TA1HlLrDhUVWk0Htik3J/[email protected]>
Newsgroups gmane.comp.freedesktop.dbus
Message-ID <[email protected]>
On Tue, Mar 13, 2018 at 12:40:10PM +0000, Simon McVittie wrote:
> tl;dr: Definitely use GDBus if you're multi-threaded.

Thanks for the comprehensive response below - looks like we'll
take the GDBus route based on this info...

> 
> On Tue, 13 Mar 2018 at 10:03:04 +0000, Daniel P. Berrange wrote:
> > Historically since I recall lots of pain around thread safety of libdbus,
> > but bugzilla [1] suggests much (all ?) of this has been addressed.
> 
> I think all of the known thread-safety bugs have been fixed (at least
> on Unix), leaving only the unknown thread-safety bugs (plus a few on
> Windows). https://bugs.freedesktop.org/show_bug.cgi?id=102839 was the
> most recent.
> 
> Honestly, I still wouldn't trust libdbus to be fully thread-safe. Full
> thread-safety is hard, and full thread-safety without having a coherent
> event loop model is harder. libdbus is "bring your own event loop" so it
> can never have a particularly good conceptual model for what runs where,
> and in particular it does not have any way to schedule callbacks to be
> called in the context (thread) where the user that set up that callback
> might expect it to be called.
> 
> fd.o#102839 was a bug in code that was already meant to be thread-safe
> since at least 2005, and was previously fixed in 2005, 2006, and twice
> in 2010. I think the fact that we are still finding bugs in the locking
> model in 2018 should tell you something!
> 
> GDBus (in GIO) is a lot better designed for multi-threaded use. It
> requires the GLib main loop, so it can say "you must iterate each GLib
> main context in a thread that holds the relevant lock" and leave it
> at that; and it can hand off callbacks to the thread where the library
> user expects them to be called.
> 
> > Also what is
> > the minimum version of libdbus one should consider if using threads ?
> 
> 1.12.4, and be prepared to require newer 1.12.x branches when you find
> and fix further multi-threading issues. The older 1.10 and 1.8 branches
> are still supported, but mostly only for security and regression fixes;
> they didn't receive patches for fd.o#102839.
> 
> > For GIO DBus[2] I'm not finding clear docs about usage with threaded object 
> > dispatch.
> 
> The general rule for GDBus is that synchronous (blocking) operations
> are OK in any thread, async operations are OK in the main thread
> and in any thread that has set up its own thread-default main context
> (g_main_context_push_thread_default()), and whatever main context is the
> thread-default at the time you start an async operation (connect to the
> bus, call a method, connect to a signal), that is the same main context
> where the corresponding callback will be invoked.
> 
> For instance, g_dbus_connection_call() says
> 
>     When the operation is finished, callback will be invoked in the
>     thread-default main context of the thread you are calling this
>     method from
> 
> and g_dbus_connection_signal_subscribe() says
> 
>     Note that callback will be invoked in the thread-default main context
>     of the thread you are calling this method from.
> 
> If other documentation is unclear, please contribute GLib patches to
> clarify it (since you know where you expected to find it!) via the GNOME
> infrastructure.
> 
> > Presumably, the implication is that all the DBus protocol I/O 
> > will still take place via the main event thread
> 
> No, GDBus does all the actual D-Bus I/O in a worker thread behind the
> scenes. The worker thread doesn't run user-supplied code, which means all
> threads that do run user code (including the main thread) are equal from
> GDBus' perspective, forcing the authors of GDBus to get the locking right.
> 
> You can see this worker thread in `pstree -t` output, as the `gdbus`
> thread. virt-manager is an example of a program in the libvirt family
> that has a gdbus thread (or at least, it does on my laptop).
> 
> > Presumably [...] something like GTask
> > would have to be used to execute object dispatch asynchronously by spawning
> > threads on demand for operations with long execution time.
> 
> I think GAsyncResult is a good interface for async operations (known as
> "promises" in some non-GLib ecosystems) and GTask is a very convenient
> way to implement or work with async results, but in my experience it's
> relatively rare that you will need to use g_task_run_in_thread() or
> g_task_run_in_thread_sync() with GDBus, because all the time-consuming
> GDBus APIs like "connect to bus" and "call a method" have an asynchronous
> version anyway - so you can mostly just work with GAsyncResult and
> callbacks/"promises" in your main thread, in the same way you would for
> networking or libdbus. You start a time-consuming operation and go back
> to your main loop, and some seconds or minutes later, a callback that
> gives you the result is scheduled to be run by that main loop.
> 
> g_task_run_in_thread() is mostly there as a way to take a synchronous
> operation like file I/O and make it look like an async operation. For
> APis that are already asynchronous (like networking and D-Bus) you don't
> usually need that.
> 
>     smcv
> _______________________________________________
> dbus mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dbus
Regards,
Daniel
--
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

_______________________________________________
dbus mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dbus
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.