bus limits
Havoc Pennington
hp at redhat.com
Sun Aug 15 10:16:48 PDT 2004
On Sun, 2004-08-15 at 12:58, Colin Walters wrote:
> On Sun, 2004-08-15 at 12:35 -0400, Havoc Pennington wrote:
>
> > One approach might be to just stop reading new messages from a
> > connection when a limit is reached, though that could lead to deadlocks
> > so has its own dangers.
>
> Deadlocks in the application or in dbus?
>
In the app, e.g. the app is blocking waiting for some other message
before it processes the pending replies, or whatever.
> > I think it's likely that app authors do have to assume every message can
> > get lost - that's the nature of IPC
>
> I don't understand - barring kernel bugs, messages over pipes, TCP
> sockets, etc can't be lost. After you write data to a pipe, and get a
> success result back from the "write" call, you can be sure the app will
> get the message. I'd call them a "reliable" transport, which is what I
> thought D-BUS was aiming to be?
D-BUS is reliable in that you will get either an error or the message
will go through, but the other app can still crash or exit, or (in the
TCP case) the network can go down, or you can run out of memory. Also,
the error may be a timeout which will take a while to show up.
Reaching a D-BUS limit is basically equivalent to EAGAIN on write() to a
nonblocking socket.
I guess I shouldn't say "assume every message can get lost" - what I
mean is "assume every attempt to send a message can result in an error"
Oddly enough the limit in question here - max pending replies - is
caused by the guarantee that you will get an error, since the resource
eaten by a pending reply is the timeout error to be sent if no reply
appears.
> What's happening here is that D-BUS is returning success from
> dbus_connection_send_with_reply, but then later sending an error back?
The success value on send_with_reply() is only whether the message was
queued successfully; to know if it was sent and received you have to
wait on the DBusPendingCall to get the reply, which may be an error.
dbus_connection_send_with_reply_and_block() will block and give you the
error in this "limits reached" case.
You can't know if sending the message worked unless you block, since the
pipe may be full and sending immediately may not be possible.
> I think to handle this, if applications want to ensure the target sees a
> message, that means they have to keep messages around until they get a
> positive reply back.
Right, so to avoid that we'd have to have "block when the pipe is full"
instead of "error when the pipe is full" semantics for the bus limits.
We can certainly try to implement that. The bus limits thing just
defines "pipe is full" for us.
The issue here is basically whether to block or EAGAIN when limits are
reached.
If someone wants to try coding this, it should be fairly simple; you
just need to not read any more data from a DBusConnection while that
connection is at a max limit. I guess it should be OK to _write_ data to
the connection? If so that would help with the deadlock thing.
Havoc
More information about the dbus
mailing list