中间件 DBus - DBusWatch方式处理消息

2024-01-24 12:48

本文主要是介绍中间件 DBus - DBusWatch方式处理消息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

DBus其他方式的处理消息并不复杂,但是看了半天文档,也没看懂DBusWatch方式。网上关于如何使用DBusWatch方式的文章也很少,还好发现一位大侠贴出了一个sample,再次记录下来!
DBusWatch似乎提供了更细力度的控制,而且可以实现异步处理,glib中的绑定也是使用该方式。
引自: http://blog.csdn.net/cuijpus/archive/2008/05/25/2478825.aspx
  1. /* compile with:
  2.    gcc `pkg-config dbus-1 --cflags --libs` own-mainloop.c -o own-
  3. mainloop
  4. */
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <sys/poll.h>
  9. #include <dbus/dbus.h>
  10. #define MAX_WATCHES 100
  11. static DBusConnection *conn;
  12. static struct pollfd pollfds[MAX_WATCHES];
  13. static DBusWatch *watches[MAX_WATCHES];
  14. static int max_i;
  15. static char *progname;
  16. static DBusHandlerResult
  17. filter_func(DBusConnection *c, DBusMessage *m, void *data)
  18. {
  19.         printf("[%s] if: %s, member: %s, path: %s/n", progname,
  20.                dbus_message_get_interface(m),
  21.                dbus_message_get_member(m),
  22.                dbus_message_get_path(m));
  23.         return DBUS_HANDLER_RESULT_HANDLED;
  24. }
  25. static dbus_bool_t add_watch(DBusWatch *watch, void *data)
  26. {
  27.         short cond = POLLHUP | POLLERR;
  28.         int fd;
  29.         unsigned int flags;
  30.         printf("[%s] add watch %p/n", progname, (void*)watch);
  31.         fd = dbus_watch_get_fd(watch);
  32.         flags = dbus_watch_get_flags(watch);
  33.        
  34.         if (flags & DBUS_WATCH_READABLE)
  35.                 cond |= POLLIN;
  36.         if (flags & DBUS_WATCH_WRITABLE)
  37.                 cond |= POLLOUT;
  38.         ++max_i;
  39.         pollfds[max_i].fd = fd;
  40.         pollfds[max_i].events = cond;
  41.         watches[max_i] = watch;
  42.         return 1;
  43. }
  44. static void remove_watch(DBusWatch *watch, void *data)
  45. {
  46.         int i, found = 0;
  47.         printf("[%s] remove watch %p/n", progname, (void*)watch);
  48.         for (i = 0; i <= max_i; ++i) {
  49.                 if (watches[i] == watch) {
  50.                         found = 1;
  51.                         break;
  52.                 }
  53.         }
  54.         if (!found) {
  55.                 printf("watch %p not found/n", (void*)watch);
  56.                 return;
  57.         }
  58.         memset(&pollfds[i], 0, sizeof(pollfds[i]));
  59.         watches[i] = NULL;
  60.         if (i == max_i && max_i > 0) --max_i;
  61. }
  62. static void fd_handler(short events, DBusWatch *watch)
  63. {
  64.         unsigned int flags = 0;
  65.         if (events & POLLIN) 
  66.                 flags |= DBUS_WATCH_READABLE;
  67.         if (events & POLLOUT)
  68.                 flags |= DBUS_WATCH_WRITABLE;
  69.         if (events & POLLHUP)
  70.                 flags |= DBUS_WATCH_HANGUP;
  71.         if (events & POLLERR)
  72.                 flags |= DBUS_WATCH_ERROR;
  73.         while (!dbus_watch_handle(watch, flags)) {
  74.                 printf("dbus_watch_handle needs more memory/n");
  75.                 sleep(1);
  76.         }
  77.        
  78.         dbus_connection_ref(conn);
  79.         while (dbus_connection_dispatch(conn) ==
  80. DBUS_DISPATCH_DATA_REMAINS);
  81.         dbus_connection_unref(conn);
  82. }
  83. int main(int argc, char *argv[])
  84. {
  85.         DBusError error;
  86.         progname = argv[0];
  87.         dbus_error_init(&error);
  88.         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
  89.         if (conn == NULL) {
  90.                 printf("Error when connecting to the bus: %s/n",
  91.                        error.message);
  92.                 return 1;
  93.         }
  94.         if (!dbus_connection_set_watch_functions(conn, add_watch,
  95.                      remove_watch, NULL, NULL, NULL)) {
  96.                 printf("dbus_connection_set_watch_functions failed/n");
  97.                 return 1;
  98.         }
  99.         if (!dbus_connection_add_filter(conn, filter_func, NULL, NULL))
  100. {
  101.                 printf("Failed to register signal handler callback/n");
  102.                 return 1;
  103.         }
  104.         dbus_bus_add_match(conn, "type='signal'", NULL);
  105.         dbus_bus_add_match(conn, "type='method_call'", NULL);
  106.         while (1) {
  107.                 struct pollfd fds[MAX_WATCHES];
  108.                 DBusWatch *watch[MAX_WATCHES];
  109.                 int nfds, i;
  110.                 for (nfds = i = 0; i <= max_i; ++i) {
  111.                         if (pollfds[i].fd == 0 ||
  112.                             !dbus_watch_get_enabled(watches[i])) {
  113.                                 continue;
  114.                         }
  115.                         fds[nfds].fd = pollfds[i].fd;
  116.                         fds[nfds].events = pollfds[i].events;
  117.                         fds[nfds].revents = 0;
  118.                         watch[nfds] = watches[i];
  119.                         ++nfds;
  120.                 }
  121.                 if (poll(fds, nfds, -1) <= 0) {
  122.                         perror("poll");
  123.                         break;
  124.                 }
  125.                 for (i = 0; i < nfds; ++i) {
  126.                         if (fds[i].revents) {
  127.                                 fd_handler(fds[i].revents, watch[i]);
  128.                         }
  129.                 }
  130.         }
  131.         return 0;
  132. }

这篇关于中间件 DBus - DBusWatch方式处理消息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/639746

相关文章

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

Mybatis的分页实现方式

《Mybatis的分页实现方式》MyBatis的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异,对Mybatis的分页实现方式感兴趣的朋友一起看看吧... 目录​1. 原生 SQL 分页(物理分页)​​2. RowBounds 分页(逻辑分页)​​3. Page

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流