libdbus and edge triggered watches

Simon McVittie simon.mcvittie at collabora.co.uk
Mon May 21 10:18:56 PDT 2012


On 21/05/12 13:58, Nicolas Cavallari wrote:
> Looking at the code, libdbus does not seem to support edge triggered
> watches. Edge triggered support would essentially mean that libdbus
> must read()/write() from/to the fd until it returns EAGAIN.

Correct; it doesn't do that.

Is there any particular reason why you want an edge-triggered watch?

> From what i see, the only limitation seems to come from the default
> value of the max_bytes_{read,written}_per_iteration variables. I think
> that setting them to an arbitrary high number should be enough to make
> libdbus work with edge triggered epoll.

This...

> The alternative would be to call the (wrapped) dbus_watch_handle()
> repeatedly until the fd is not readable/writable anymore

... would essentially be equivalent to this, but inside libdbus.

As far as I'm aware, the reason for the max_bytes_*_per_iteration
variables is mainly to avoid main loop "starvation": if your process
sees/produces sufficiently rapid D-Bus traffic that there is always
something to read/write, then none of your other fds (including,
perhaps, the one telling you to slow down or exit!) will ever be polled.

Relatedly, it avoids arbitrary memory consumption under extremely heavy
traffic: if you keep reading from a fd indefinitely, without ever
pausing to do what libdbus calls "dispatching" (sending in-memory
messages to their consumers), and there's always another message to
read, then the messages will be queued in memory forever, and will never
actually be dispatched to their consumers and (hopefully) freed.

If you use edge-triggered watches with busy-reading like this, you're
basically always going to be vulnerable to those problems. If you're OK
with that, call dbus_watch_handle() in a loop, I suppose.

Alternatively, use level-triggered polling, or wrap an edge-triggered
epoll in a higher-level construct that remembers that the D-Bus socket
is still readable/writeable and interleaves reads/writes/dispatching
with polling other sockets (with the timeout set to zero for as long as
you know reads/writes are pending).

    S


More information about the dbus mailing list