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

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息,然后展示在页面上。 效果展示 首次发送需要设置昵称 发送消息与消息展示 提示用户不能发送空消息 后端接口 发送消息 DB = []@ro

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

脏页的标记方式详解

脏页的标记方式 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了有效地管理这些脏页并确保数据的一致性,数据库需要对脏页进行标记。了解脏页的标记方式对于理解数据库的内部工作机制和优化性能至关重要。 二、脏页产生的过程 当数据库中的数据被修改时,这些修改首先会在内存中的缓冲池(Buffer Pool)中进行。例如,执行一条 UPDATE 语句修改了某一行数据,对应的缓

开源分布式数据库中间件

转自:https://www.csdn.net/article/2015-07-16/2825228 MyCat:开源分布式数据库中间件 为什么需要MyCat? 虽然云计算时代,传统数据库存在着先天性的弊端,但是NoSQL数据库又无法将其替代。如果传统数据易于扩展,可切分,就可以避免单机(单库)的性能缺陷。 MyCat的目标就是:低成本地将现有的单机数据库和应用平滑迁移到“云”端

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似