低级DBus C API主循环
当试图为DBus回复使用回调函数时,我遇到了创建一个良好/工作正常的主循环的问题。低级DBus C API主循环
我想要做的事很简单,做一个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->状态标志MY_DBUS_STATUS_STOPPING和等待的线程加入到停止应用程序。如果线程在dbus_connection_read_write_dispatch(..)函数中被阻塞,则这不起作用。如果我想要应用程序停止快速,那么我需要指定一个非常短的超时。我不能以其他方式唤醒阻塞的线程吗?
更严重的是,使用此代码我没有从我调用的方法中获得任何回调。如果我添加一些fprintf(..)写入标准输出,我可能会突然收到我的回调。这似乎很随机,所以也许会出现某种僵局?我试着在发送消息和使用_set_notify(..)函数添加回调函数之间有一个dbus_connection_flush(..)。没有任何区别......但是在同一个地方打印一些字母到stdout可以解决问题。打印到dbus-main-loop中标准输出的空白“;”似乎做有时伎俩......
因此,任何人谁拥有使用低级别的dbus API的例子与异步方法一起,即不使用_block(..)?
可以按如下方式创建一个简单的DBus申请...
要设置一个服务器来处理传入的消息,请致电dbus_connection_register_object_path
传递一个虚函数表包含函数指针来处理消息。如:
{ .unregister_function = UnregisteredMessage, .message_function = ServiceMessage }
发送新邮件,打电话dbus_connection_send_with_reply
然后dbus_pending_call_set_notify
一个回调函数来处理答复相关联。
接下来你将需要服务DBus。这可以在单独的线程或通过用在同一线程非阻塞调用周期性调用来完成,如下所示:
/* Non-blocking read of the next available message */
dbus_connection_read_write (MyDBusConnection, 0) ;
while (dbus_connection_get_dispatch_status (MyDBusConnection) == DBUS_DISPATCH_DATA_REMAINS)
{
dbus_connection_dispatch (MyDBusConnection) ;
}
这里有使用DBUS C API的一些很好的例子:http://www.matthew.ath.cx/misc/dbus