D-Bus保证消息传递吗?

4
我想知道当直接通过低级别C API调用dbus_connection_send_with_reply使用D-Bus时,它是否保证消息的传递?
更具体地说,它是否保证将消息的单个实例传递到目的地,或者如果失败,则返回错误回复?
我了解接收应用程序可能不会对方法发出回复,在这种情况下,D-Bus将在超时后返回错误。但是,D-Bus协议是否涵盖了所有其他潜在的故障?
2个回答

4

简而言之:

无法保证消息的传递。但是,即使消息未被传递,您也可以期望收到错误回复。

如果使用DBUS_TIMEOUT_INFINITE,则可能永远等待回复。如果函数调用返回FALSE,则不会有回复。否则,您将获得恰好一个回复。


我是D-Bus消息传递协议规范和dbus参考实现的上游维护者。

术语:调用dbus_connection_send_with_reply()的进程是客户端,预计回复的进程是服务。通常情况下,会有一个dbus-daemon在中间,尽管在特殊情况下可以直接连接到服务(如果您这样做,则应该已经知道您正在这样做)。

总体而言,API保证是,如果dbus_connection_send_with_reply()成功(返回TRUE),则您将看到恰好一个回复,它可以是成功返回(仅当消息已传递时)或错误(无论消息是否已传递都可能发生)。如果由于内存不足或其他病态条件(返回FALSE)而失败,则不会看到任何回复。实现会付出相当大的努力来确保这一点。

dbus_connection_send_with_reply()返回之前,它会预分配合成错误消息,您将在超时时收到该消息;如果失败,则不发送该消息并且dbus_connection_send_with_reply()失败。因此,即使dbus-daemon或传输将真实(成功或错误)回复放在地板上,您最终也会收到超时错误消息。(参考:git grep _dbus_pending_call_set_timeout_error_unlockeddbus源代码的副本中)

唯一例外的是,如果对超时使用DBUS_TIMEOUT_INFINITE(在这种情况下:您要求了它,您得到了它)。在这种情况下,存在永远看不到回复的情况:服务从不响应但仍留在总线上;或者,更病态的是,服务从不响应并离开总线,而dbus-daemon在尝试传递合成的错误回复以报告将永远没有来自服务的回复时耗尽内存。


值得指出的是,其他D-Bus客户端库(如GDBus)具有类似的语义,保证对发送的消息只有一个响应(回复消息或错误)。 - Philip Withnall

1

从您发布的链接中,“发送方或接收方的断开/崩溃”是另一种可能性。此外,如果存在阻止消息的安全策略,则会出现错误而不是通过消息。 因此,您可能无法收到回复。 - TaborKelly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接