dbus_connection_send_with_reply() shouldn't return TRUE on a disconnected connection

Havoc Pennington hp at pobox.com
Fri Apr 17 17:40:58 PDT 2009

Thinking about it more, I'm guessing the right place for this to fail
is probably where the syscalls are made to transfer the fd. You have
to handle that case anyway. Look at generate_local_error_message in
dbus-connection.c (a non-local error message can also come from the
peer if the syscalls fail on that side).

dbus_connection_send() needs to cope also, and it has no way to report
errors other than OOM, so generating a local (or remote) error reply
message will handle that.

The failure of send_with_reply() when it returns a NULL
DBusPendingCall is kind of a weird special case. I think it was added
because we clean up pending calls on disconnect so it would have been
a mess to allow adding more after that, or something. See appended
changelog. If the connection disconnects before the pending call gets
a reply, an async error reply message is generated, so the "early
fail" of returning a NULL pending call is a bit odd, in fact. I guess
we need to get the error replies in front of the Disconnected message
which is guaranteed to be the last message, so that may be why it
works as it does, we can't error reply on stuff sent post-disconnect.
It looks like dbus_connection_send() once the connection is
disconnected just queues the messages and never does anything with
them; afaik it could just drop them on the floor instead with the same
effect, that just hasn't been special-cased, it would be an
optimization. With send_with_reply, dropping on the floor is bad
because you'd have a PendingCall that never "finished"; so not
returning a PendingCall is a solution to that.

The point is, sending stuff over a disconnected connection /dev/null's
that stuff rather than reporting an error... the normal practice for
an error is to return an error reply message, but in the disconnected
case, that isn't possible since it's guaranteed messages don't keep
turning up once the Disconnected signal arrives.

So to solve the fds-cannot-be-sent problem, what's wanted is more the
"normal" error approach, which is an error reply message. That should
then just work with send(), send_with_reply(), etc., and treats
local-fails-to-send-fd basically the same as remote-fails-to-read-fd.


2006-07-13  John (J5) Palmieri  <johnp at redhat.com>

	* dbus-connection.c (dbus_connection_send_with_reply): return TRUE
	and set pending_reply out arg to NULL is connection is disconnected
	(connection_timeout_and_complete_all_pending_calls_unlocked): New
	static method for cleaning up pending calls on disconnect
	(_dbus_connection_get_dispatch_status_unlocked): If we have pending
	calls queued timeouts on disconnect

	 * dbus/dbus-pending-call.c (_dbus_pending_call_set_connection):

More information about the dbus mailing list