<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p><font face="DejaVu Sans">Thanks for the reply. I completely
understand what using libdbus implies, and I will eventually
integrate this with libevent. But for now I just want an
implementation as simple as possible to validate the
functionality that I want to implement before going further. I
conceded to run read_write_dispatch with a 1-second timeout,
it's good enough for now. Thanks again.</font><br>
</p>
<div class="moz-cite-prefix">On 6/18/20 7:26 PM, Simon McVittie
wrote:
</div>
<blockquote type="cite" cite="mid:20200618162641.GA647660@horizon">
<pre class="moz-quote-pre" wrap="">Expanding on that: read_write_dispatch is a simple solution for
single-threaded D-Bus clients like dbus-monitor, and is not really
fit-for-purpose in something with multiple threads.
Using a real main-loop framework (GLib's main loop, Qt's main loop,
libevent, libev, that sort of thing) is likely to be better-tested than
making your own artisanal dispatcher. Unfortunately, libdbus tries to
be all things to all people, so it half-supports all main loops and no
main loop equally, rather than fully supporting one and rejecting all
the others.
The libdbus API documentation has some wise words about libdbus which
probably apply here:
This manual documents the *low-level* D-Bus C API. **If you use this
low-level API directly, you're signing up for some pain.**
I think the key thing for interrupting the main loop is likely to be
dbus_connection_set_wakeup_main_function(), which needs to be called
providing a callback that will wake up the dispatching thread's poll()
(or equivalent).
For example,
<a class="moz-txt-link-freetext" href="https://gitlab.freedesktop.org/dbus/dbus-glib/-/tree/dbus-gmain">https://gitlab.freedesktop.org/dbus/dbus-glib/-/tree/dbus-gmain</a>
is a fairly complete example of integrating libdbus
with the GLib main loop. The callback that it passes to
dbus_connection_set_wakeup_main_function() uses g_main_context_wakeup()
to wake up the central poll() call in GLib. Historically
g_main_context_wakeup() was implemented as a pipe-to-self, and recent
versions optimize that by using an eventfd on Linux.
If "pipe-to-self" means nothing to you, then implementing your own event
loop is probably going to require more learning than would be productive
or efficient.
You could also consider using a different D-Bus implementation instead
of libdbus. GDBus (part of GLib) is specifically designed to be able
to share a single D-Bus connection between multiple threads, by using
GLib's GMainContext abstraction for threading and dispatching, and doing
the actual I/O in its own private thread.
I would normally also suggest systemd's sd-bus, but sd-bus is specifically
not multi-threaded, so probably not that one for your use-case.
Having all your D-Bus I/O happen in one designated thread, and making
all other threads that want to use D-Bus post messages to/from the D-Bus
thread instead of touching D-Bus APIs directly, is another possible route;
libdbus and sd-bus work well with that approach. This is close to how
GDBus works behind the scenes.
Regards,
smcv
_______________________________________________
dbus mailing list
<a class="moz-txt-link-abbreviated" href="mailto:dbus@lists.freedesktop.org">dbus@lists.freedesktop.org</a>
<a class="moz-txt-link-freetext" href="https://lists.freedesktop.org/mailman/listinfo/dbus">https://lists.freedesktop.org/mailman/listinfo/dbus</a>
</pre>
</blockquote>
</body>
</html>