Method calls without timeouts

Scott James Remnant scott at
Tue Jul 22 11:15:29 PDT 2008

On Sat, 2008-07-19 at 05:33 -0400, Havoc Pennington wrote:

> The timeout on the client side (in DBusConnection/PendingCall) is
> intended to keep the client from blocking indefinitely if the other
> end is dead. This timeout applies with a bus daemon, or with a direct
> connection to another app with no daemon. This timeout can be thought
> of as the max time the user will wait for an error message if there's
> a deadlock or the other end of the connection is wedged. So by default
> it should probably be short enough to give an error message before
> someone forgets what they clicked on, but long enough never to happen
> unless things are genuinely broken. For long-running operations, a
> client could manually make it longer for a particular call. The
> timeout here is analogous to the timeout a web browser would put on an
> HTTP request.
I fully agree that the default should be short, and my patches do not
make any changes to the default client-side timeout which you get when
you specify -1.

Clients do need to be able to make the choice to permit longer timeouts.
This is especially important for Upstart where the "Start" method call
may take a little while, if the application takes a while to start.

We've already had issues on the Live CD where it was slow enough that
D-Bus timed out, and that was just with D-Bus's own native service

> The timeout in the bus daemon is because the bus daemon allocates
> resources for each expected method call reply. The resources are a
> record to track whether the reply is in fact allowed (only expected
> replies are allowed on system bus). Because, like the kernel, the
> system bus is not supposed to allow clients to allocate infinite
> resources, each "expected reply" record has a finite lifetime
> (timeout), and there's also a max number of expected reply records.
I could find no evidence of any code to limit the maximum number of
expected reply records, which is a shame, because this is the right way
to limit resources.

The timeout here is bizarre, because it clamps all bus method calls to a
maximum of 5 minutes, even when the client has given a longer timeout.

Obviously I care about service activation and management, and the length
of time that the "Start" method may take.  This method returns once the
service is actually started, this is sensible, it means that code like:

	apache = upstart.GetJobByName("apache")
	print urlopen("http://localhost/").read()

Will actually do the right thing.

There's a meme going around that this is the wrong way to do such calls,
and instead one should return immediately and emit a signal to indicate

This is hideous for a number of reasons, notably:

 - race condition between the reply and the signal emission:

	req_id = apache.Start()
	# signal may be emitted here, before we have a match on it
	bus.add_match_string(START_SIGNAL_MATCH % req_id)

 - which requires you to know the id before you need it, icky:

	request = apache.Request()

 - you now have to listen for the signal from the bus daemon indicating
   that the remote end has gone away, and cancel your own callback

 - you also have to listen for the signal indicating that your own
   connection has gone away, and cancel your callback

 - if you actually do want a timeout, you have to implement that too!

 - if your application is trivial and you want blocking behaviour of
   D-Bus, you have to wrap the dispatch loop to push your reply signals
   to the top so they are dealt with

In fact, every single thing is just re-implementing the code that
already exists to deal with replies.  And the only reason you wouldn't
use a reply is because D-Bus has hokey timeout behaviour ;)

Scott James Remnant
scott at
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : 

More information about the dbus mailing list