Re: Synchronous method in asynchronous signal callback
Simon McVittie <simon.mcvittie-ZGY8ohtN/[email protected]>
| Newsgroups | gmane.comp.freedesktop.dbus |
|---|---|
| Organization | Collabora Ltd. |
| Message-ID | <[email protected]> |
On 14/05/15 16:16, Marco Bascetta wrote: > I'm using libdbus with a poll mainloop. I monitor the DBusWatch file > descriptor to call "dbus_watch_handle" and "dbus_connection_dispatch". My first recommendation would be to use a main loop designed by people who have thought a lot about main loops, like GLib, Qt, libevent or libev, rather than writing your own. I prefer to use GLib myself. If using GLib, you could use GDBus instead of libdbus: it's an interoperable D-Bus reimplementation with a much higher-level design (you probably saw the warnings in the libdbus documentation about how it's low-level and painful to use). Crucially, it knows which main loop you can be expected to use (the GLib one) so it can integrate with that one perfectly; it doesn't have to jump through hoops to be main-loop-agnostic like libdbus does, which just results in libdbus integrating with every main loop equally poorly. Similarly, if using Qt, you could use QtDBus, which is a convenient wrapper around libdbus. > It works without deadlock or message missing, but the signals received > during the "invoke_method" are delayed until another signal is received > (watch fd unlocks the poll) (and this could occurs much later...) > > Could you suggest me how to resolve this issue without using the > asynchronous calls only? My next recommendation would be: relax your constraints, and use asynchronous calls. Doing a synchronous "pseudo-blocking" call[1] inside a filter function is never going to work amazingly well. However, if you cannot do that, I think you might need either a pipe-to-self[2] or (on modern Linux) an eventfd (which is just a "cheaper" way to do a pipe-to-self), to wake up the poll() "from a distance". For instance, in GLib this is g_main_context_wakeup(), which uses an eventfd on Linux or a pipe elsewhere. The fact that you need to set force_dispatch makes me suspicious. You haven't provided pseudocode for your actual main loop or how you hook up the watch(es), but I wonder whether you aren't using all the necessary integration points. dbus-glib is deprecated and should not be used, but http://cgit.freedesktop.org/dbus/dbus-glib/tree/dbus/dbus-gmain.c does provide an example of a complete main loop hookup including all the necessary glue: * watches * timeouts * separate read and write watches for the same fd (yes this is silly, but the mainloop integration glue API doesn't give us a way to signal that the wants-read/wants-write state has changed, and I don't think we can assume that every existing implementation re-polls the flags when a watch is disabled and re-enabled) * dbus_connection_set_wakeup_main_function(), which I think might be the one you're missing? [1] http://smcv.pseudorandom.co.uk/2008/11/nonblocking/ [2] e.g. http://skarnet.org/software/skalibs/libstddjb/selfpipe.html -- Simon McVittie Collabora Ltd. <http://www.collabora.com/> _______________________________________________ dbus mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dbus