【问题标题】:dbus_connection_send failed duo to Disconnectiondbus_connection_send 由于断开连接而失败
【发布时间】:2017-11-09 02:33:31
【问题描述】:

最近使用dbus作为IPC,但遇到一些问题:

  • 如何处理发送消息失败:dbus_connection_send可以发送dbus消息,但是文档说:

    因为这只会对消息进行排队,所以它失败的唯一原因是 记忆力不足。即使断开连接也不会出错 被退回。如果函数由于内存不足而失败,则返回 错误的。该功能永远不会因其他原因而失败;即使 连接已断开,但您可以将传出消息排队 显然不会发送。

    那么当连接断开时如何处理这种情况,以确保传出队列中的所有消息都发送成功

  • dbus_connection_dispatch收到消息时如何处理断开连接,我的代码是这样的,但是我认为重新连接到dbus时会丢失一些消息

void DbusMessageWrapper::messageDispatchThreadFunction() { 开始: 结构 pollfd *pollFd = &m_pollFd; if (!dbus_connection_set_watch_functions(m_dbusConnection, addWatch, removeWatch, NULL, this, NULL)) { TONLY_ERROR("dbus_connection_set_watch_functions 失败"); 返回; }

if (!dbus_connection_add_filter(m_dbusConnection, messageProcessFunction, this, NULL)) { TONLY_INFO("dbus_connection_add_filter failed"); return; } int iret = 0; for (; !m_isShuttingDown;) { iret = poll(pollFd, 1, -1); if (iret < 0) { ///If poll return -1, we think that poll does not work on current plateform, so emit a ALERT log and exit application TONLY_ALERT("poll for dbus fd failed, the application will exit."); exit(1); } /** * If poll return POLLHUP/POLLRDHUP/POLLERR event, we think the dbus connection have disconnected from dbus deamon * we should release the request name and close current dbus connection, then reconnect to the dbus deamon, * aslo add the message observer watch to dbus connection again */ if ((pollFd->revents & POLLHUP) || (pollFd->revents & POLLRDHUP) || (pollFd->revents & POLLERR)) { TONLY_ERROR("poll error event occured, will reconnect to dbus deamon."); dbusDisConnect(); dbusConnect(); ///reinstall the message observer auto observers = m_observers; m_observers.clear(); for (auto it = observers.begin(); it != observers.end(); it++) { addMessageObserver({it->second}); } goto start; } unsigned int flags = 0; if (pollFd->revents & POLLIN) { flags |= DBUS_WATCH_READABLE; } ///wait for there are enougth memory while (!dbus_watch_handle(m_watch, flags)) { TONLY_ERROR("Dbus need more memory"); sleep(1); } while (dbus_connection_get_dispatch_status(m_dbusConnection) == DBUS_DISPATCH_DATA_REMAINS) { dbus_connection_dispatch(m_dbusConnection); } }

}

【问题讨论】:

    标签: dbus


    【解决方案1】:

    强烈建议您使用除 libdbus 之外的 D-Bus 库其他,因为正如您所发现的那样,libdbus 的正确使用非常繁琐。如果可能,请改用GDBusQtDBus,因为它们是更高级的绑定,更易于使用。如果您需要较低级别的绑定,sd-bus 比 libdbus 更现代。

    两个更高级别的 D-Bus 库处理消息传输失败和断开连接的方式与 libdbus 不同。由于尚不完全清楚您遇到了什么问题,我建议您阅读他们的文档,看看它们是否符合您的用例。

    【讨论】:

    • sd-bus 在 libsystemd 中,我可以在不安装 libsystemd 的情况下使用 sd-bus api
    • 不,你不能。如果您的许可证兼容,您可能会将 sd-bus 实现复制到您的源代码中。
    猜你喜欢
    • 2012-12-13
    • 2017-01-06
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    相关资源
    最近更新 更多