我想知道D总线在直接通过底层call调用dbus_connection_send_with_reply
使用时是否保证消息传递。
更具体地说,它是否保证将消息的单个实例传递到目标,或者如果它失败,则返回错误答复?
据我所知,接收应用程序可能不会发出对方法的答复,在这种情况下,D总线将在超时后返回错误。然而,D总线协议是否涵盖了所有其他潜在的故障?
发布于 2017-07-06 13:07:37
tl;dr:
交货永远不能保证。但是,即使没有传递消息,您也可以期望错误回复会这样说。
如果您使用DBUS_TIMEOUT_INFINITE
,您可能会永远等待回复。如果函数调用返回FALSE
,则不会有应答。否则,你就会得到一个。
我是D总线的上游维护者,消息传递协议规范,以及D总线的参考实现。
术语:调用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
源代码的副本中)
API保证的一个例外是如果您使用DBUS_TIMEOUT_INFINITE
作为超时(在这种情况下:您请求它,您得到它)。在这种情况下,您将永远看不到答复:要么服务永远不会响应,而是停留在总线上;或者,更病理地说,服务永远不会响应并离开总线,并且dbus-daemon
在试图传递错误应答时耗尽内存,而错误应答是它合成的一种报告服务永远不会有回复的方式。
发布于 2017-07-05 22:47:59
这取决于底层传输层,但除非您让它处理unix域套接字或TCP之外的其他内容(如果您需要询问,则不需要),否则可以安全地假定您将收到答复。
资料来源:
https://dbus.freedesktop.org/doc/dbus-tutorial.html#addresses
https://lists.freedesktop.org/archives/dbus/2007-June/008094.html
https://stackoverflow.com/questions/42158160
复制相似问题