dbus_connection_send_with_reply
使用D-Bus时,它是否保证消息的传递?更具体地说,它是否保证将消息的单个实例传递到目的地,或者如果失败,则返回错误回复?
我了解接收应用程序可能不会对方法发出回复,在这种情况下,D-Bus将在超时后返回错误。但是,D-Bus协议是否涵盖了所有其他潜在的故障?
简而言之:
无法保证消息的传递。但是,即使消息未被传递,您也可以期望收到错误回复。
如果使用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_unlocked
在dbus
源代码的副本中)
唯一例外的是,如果对超时使用DBUS_TIMEOUT_INFINITE
(在这种情况下:您要求了它,您得到了它)。在这种情况下,存在永远看不到回复的情况:服务从不响应但仍留在总线上;或者,更病态的是,服务从不响应并离开总线,而dbus-daemon
在尝试传递合成的错误回复以报告将永远没有来自服务的回复时耗尽内存。