Reputation: 940
I would like to know if D-Bus guarantees message delivery when used directly through the low level C API call dbus_connection_send_with_reply
?
More specifically, does it guarantee that a single instance of a messages is delivered to the destination or if it fails that an error reply is returned?
I understand that the receiving application may not issue a reply to a method in which case D-Bus will return an error after a timeout. However, are all other potential failures covered by the D-Bus protocol?
Upvotes: 4
Views: 1042
Reputation: 56
tl;dr:
Delivery can never be guaranteed. However, even if the message is not delivered, you can expect an error reply to say so.
If you use DBUS_TIMEOUT_INFINITE
, you might wait forever for a reply. If the function call returns FALSE
, there will be no reply. Otherwise, you will get exactly one.
I am an upstream maintainer of D-Bus, the message passing protocol specification, and dbus, the reference implementation of D-Bus.
Terminology: your process calling dbus_connection_send_with_reply()
is the client, the process that is expected to reply is the service. Normally there would be a dbus-daemon
in between, although connecting directly to a service is possible in specialized situations (if you are doing this, then you should already know you are doing so).
In general, the API guarantee is that if dbus_connection_send_with_reply()
succeeds (returns TRUE
), you will see exactly one reply, which can either be a successful return (only if the message was delivered) or an error (which can happen whether the message was delivered or not). If it fails due to out-of-memory or other pathological conditions (returns FALSE
), you will see exactly no replies. The implementation goes to considerable lengths to ensure this.
Before dbus_connection_send_with_reply()
returns, it preallocates the synthetic error message that you will receive if the call times out; if that fails, the message is not sent and dbus_connection_send_with_reply()
fails. So even if the dbus-daemon
or the transport drops the real (success or error) reply on the floor, you will get the timeout error message eventually. (Reference: git grep _dbus_pending_call_set_timeout_error_unlocked
in a copy of the dbus
source code)
The one exception to that API guarantee is if you use DBUS_TIMEOUT_INFINITE
for the timeout (in which case: you asked for it, you got it). In that case, there are situations where you will never see a reply: either the service never responds but remains on the bus; or, more pathologically, the service never responds and leaves the bus, and the dbus-daemon
runs out of memory while attempting to deliver the error reply that it synthesizes as a way to report that there will never be a reply from the service.
Upvotes: 4
Reputation: 552
This is dependent on the underlying transport layer, but unless you got it working on something other than unix domain sockets or TCP (if you got to ask, you don't), it is safe to assume you will receive a reply.
Sources:
https://dbus.freedesktop.org/doc/dbus-tutorial.html#addresses
https://lists.freedesktop.org/archives/dbus/2007-June/008094.html
Upvotes: 1