C-API Examples

Havoc Pennington hp at redhat.com
Thu May 4 20:50:23 PDT 2006


Kosina, Martin wrote:
> 
> Matt wrote:
>> http://www.matthew.ath.cx/misc/dbus/ is one that I compiled when I
>> worked it out while writing a simple app and the Java bindings.
> 
> Thanks - that is very helpful. I can get everything to connect/register
> on the bus, but it seems that _dbus_connection_read_write_dispatch()
> never does any reading (so the send/receive or listen/query pairs never
> exchange anything). (It seems status is always DBUS_DISPATCH_COMPLETED
> after the initial exchange, hence
> _dbus_connection_do_iteration_unlocked() never gets subsequently called
> ?) I put a breakpoint at _dbus_read() and it never gets hit...
> 
> Has anyone tried these recently ? I suspect something might have
> changed, because _dbus_connection_read_write_dispatch() doesn't even run
> without some //hacking due to a call to _dbus_return_val_if_fail(),
> which appears to assert that the function call does not start with an
> '_' (leading me to believe its been a while since this actually worked -
> but perhaps I am missing something simple ?).

I don't see the return_val_if_fail in it right now?
http://webcvs.freedesktop.org/dbus/dbus/dbus/dbus-connection.c?rev=1.118&view=markup

On the larger question: DBUS_DISPATCH_COMPLETED is not related to 
reading or writing. The overview docs for DBusConnection talk a bit 
about what the dispatch status means:
http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#_details
See also the docs on read_write_dispatch:
http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#g7843e31742a11e0551a52f18370d8c8e

In short dispatching is about processing the message queue by calling 
registered handlers. This is distinct from reading/writing stuff off the 
socket into the message queue.

One of the reasons the low level library is low level is that it can be 
used in a lot of different ways. In a GLib or Qt app, you can just 
assume a mainloop and hardwire "how it works"

When writing your own app, there are a number of choices:
  - if you have a main loop (a poll() or select() with non-dbus stuff in
    the fd set) then you can use the DBusWatch/DBusTimeout stuff to
    integrate dbus fds into those you will watch
  - if you are only dealing with dbus, read_write_dispatch() can be used
    to create a trivial dbus-only mainloop like
    "while (read_write_dispatch()) { ; }"
  - if you are in an environment such as Java which normally uses threads
    instead of select/poll, you can use a thread (probably with the
    trivial dbus-only mainloop inside)

If you use DBusWatch/DBusTimeout to integrate dbus into your own main 
loop, when you dbus_watch_handle() it only reads messages into the 
message queue. The dispatch-related functions are used to then process 
the queue.

In general you have to be careful that your main loop logic checks the 
dispatch status anytime you do some reading, or you could go back to the 
poll() while messages are still in the queue, resulting in not seeing 
those messages until more messages arrive. You can also use 
set_dispatch_status_function() rather than "polling" the dispatch status.

As yet another option, you can ignore all the dispatch() stuff, and 
instead of registering handlers with DBusConnection, just manually pull 
messages off the queue with dbus_connection_pop(). This is similar to 
how Xlib works. It is perhaps the simplest way to use dbus, but is 
pretty unfriendly to code modularity since one piece of code will be 
eating all the messages without letting any other code sign up to see them.

Maybe the key insight to reduce confusion is that the functions in 
dbus-connection.h don't all make sense together. You sort of have to 
decide how you'll do things; if you're using a mainloop, then 
read_write_dispatch() makes no sense, and if you're going to block, then 
all the DBusWatch etc. stuff can be ignored.

The other major point is that DBusConnection is both a socket and a 
message queue, and to understand the methods on DBusConnection you need 
to know how they each relate to both the IO and the message queue 
processing.

When using a binding that already knows what to do (glib/qt with their 
main loops, java with threads, etc.) then there's no need to think about 
all this, thankfully ;-)

Hope that helps.

Havoc




More information about the dbus mailing list