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

相关文章

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二