Re: Synchronous method in asynchronous signal callback
Marco Bascetta <[email protected]>
| Newsgroups | gmane.comp.freedesktop.dbus |
|---|---|
| Message-ID | <[email protected]> |
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) _______________________________________________ dbus mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dbus