Synchronous method in asynchronous signal callback

Marco Bascetta marco.bascetta at sadel.it
Thu May 14 10:10:12 PDT 2015


Thanks, see my replies below.

On 14/05/15 17:54, Simon McVittie wrote:
> 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.
I know, I know. But I can't.
My goal is to create a library for various systems that already have 
their own (working) mainloop based on poll, epoll or libevent.

So, I should only provide the "fd", a "dispatch" method and some other 
callback interface.

>> 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
I'll try to follow the dbus-gmain.c implementation and your advices and 
I let you know.

Instead, I already saw dbus_connection_set_wakeup_main_function and it 
wasn't useful.

Anyway, if I fail with your suggestions, I will change the 
implementation to be a complete asynchronous solution.
( Reference [1] is very interesting!! )

Thanks for your support.

Regards,

-- 
Marco Bascetta - Sadel SpA
Software Development
Via Serenari 1, Castel Maggiore (BO)



More information about the dbus mailing list