当尝试使用回调函数进行 DBus 回复时,我陷入了创建良好/运行良好的主循环的困境。
我想做的很简单,进行 DBus 调用并指定一个在回复到来时应该调用的函数。这是因为在计算并到达回复之前,我不想一直阻塞我的线程。
我首先使用 dbus_connection_send_with_reply(..) 获取 DBusPendingCall,然后使用 dbus_pending_call_set_notify(..) 指定回调函数。在此之前,当连接到总线时,我已经启动了另一个线程,它应该等待响应并调用回调函数。我根本没有找到任何例子,也没有很好的文档来说明我应该如何设计这样的 dbus 主循环。我努力了:
// Main dbus loop handling data transfer and callbacks..
void *dbus_main(void *args)
{
my_dbus dbus = (my_dbus)args;
while (MY_DBUS_STATUS_STOPPING != dbus->status
&& dbus_connection_read_write_dispatch(dbus->conn, -1))
;
return 0;
}
// Start the dbus main loop in a new thread
void dbus_main_start(my_dbus dbus) {
if (!pthread_create(&dbus->th, NULL, dbus_main, dbus)) {
// PRINT ERROR
}
}
我的问题是两件事:
我尝试通过将 dbus->status 标志设置为 MY_DBUS_STATUS_STOPPING 并等待线程加入来停止应用程序。如果线程在 dbus_connection_read_write_dispatch(..) 函数中被阻塞,这将不起作用。如果我希望应用程序快速停止,那么我需要指定一个非常短的超时时间。我不能以其他方式唤醒阻塞的线程吗?
更严重的是,使用这段代码,我不会从我调用的方法中得到任何回调。如果我添加一些 fprintf(..) 来写入标准输出,我可能会突然收到我的回调。这似乎很随机,所以也许是某种僵局?我尝试在发送消息和使用 _set_notify(..) 函数添加回调之间使用 dbus_connection_flush(..) 。没有任何区别......但是在同一个地方打印一些字母到标准输出可以解决问题。在 dbus-main-loop 中打印到标准输出,插入一个空的“;” 有时似乎可以解决问题...
那么任何有使用低级dbus api和异步方法的例子的人,即不使用_block(..)?