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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值