中间件 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

相关文章

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

Jsoncpp的安装与使用方式

《Jsoncpp的安装与使用方式》JsonCpp是一个用于解析和生成JSON数据的C++库,它支持解析JSON文件或字符串到C++对象,以及将C++对象序列化回JSON格式,安装JsonCpp可以通过... 目录安装jsoncppJsoncpp的使用Value类构造函数检测保存的数据类型提取数据对json数

Redis事务与数据持久化方式

《Redis事务与数据持久化方式》该文档主要介绍了Redis事务和持久化机制,事务通过将多个命令打包执行,而持久化则通过快照(RDB)和追加式文件(AOF)两种方式将内存数据保存到磁盘,以防止数据丢失... 目录一、Redis 事务1.1 事务本质1.2 数据库事务与redis事务1.2.1 数据库事务1.

Linux磁盘分区、格式化和挂载方式

《Linux磁盘分区、格式化和挂载方式》本文详细介绍了Linux系统中磁盘分区、格式化和挂载的基本操作步骤和命令,包括MBR和GPT分区表的区别、fdisk和gdisk命令的使用、常见的文件系统格式以... 目录一、磁盘分区表分类二、fdisk命令创建分区1、交互式的命令2、分区主分区3、创建扩展分区,然后

Linux中chmod权限设置方式

《Linux中chmod权限设置方式》本文介绍了Linux系统中文件和目录权限的设置方法,包括chmod、chown和chgrp命令的使用,以及权限模式和符号模式的详细说明,通过这些命令,用户可以灵活... 目录设置基本权限命令:chmod1、权限介绍2、chmod命令常见用法和示例3、文件权限详解4、ch

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

Java中ArrayList的8种浅拷贝方式示例代码

《Java中ArrayList的8种浅拷贝方式示例代码》:本文主要介绍Java中ArrayList的8种浅拷贝方式的相关资料,讲解了Java中ArrayList的浅拷贝概念,并详细分享了八种实现浅... 目录引言什么是浅拷贝?ArrayList 浅拷贝的重要性方法一:使用构造函数方法二:使用 addAll(

Mycat搭建分库分表方式

《Mycat搭建分库分表方式》文章介绍了如何使用分库分表架构来解决单表数据量过大带来的性能和存储容量限制的问题,通过在一对主从复制节点上配置数据源,并使用分片算法将数据分配到不同的数据库表中,可以有效... 目录分库分表解决的问题分库分表架构添加数据验证结果 总结分库分表解决的问题单表数据量过大带来的性能

Python3中Sanic中间件的使用

《Python3中Sanic中间件的使用》Sanic框架中的中间件是一种强大的工具,本文就来介绍Python3中Sanic中间件的使用,具有一定的参考价值,感兴趣的可以了解一下... 目录Sanic 中间件的工作流程中间件的使用1. 全局中间件2. 路由中间件3. 异常处理中间件4. 异步中间件5. 优先级