Async DBusMessage reads using the C API

Matthew Johnson dbus at matthew.ath.cx
Mon Nov 14 07:26:29 PST 2005


On Mon, 14 Nov 2005, John (J5) Palmieri wrote:

> Attaching the patch would be nice ;-)

Whoops, try again....

Matt

>
> On Mon, 2005-11-14 at 12:54 +0000, Matthew Johnson wrote:
>> On Mon, 7 Nov 2005, John (J5) Palmieri wrote:
>>
>>> Thanks for the patch.  Can you send it in unified diff format.  It will
>>> also need a test case for both the dispatch and non dispatching methods.
>>> Though your example might be good enough for this it needs to be added
>>> as part of the diff and setup to run on make check.
>>
>> OK, attached is the current diff. I'm having some problems getting the
>> regression tests to run though. Firstly, make check doesn't start a
>> temporary bus to talk over, I'm not sure how to add in
>> tools/run-with-tmp-session-bus.sh.
>>
>> Secondly, if you run 'DBUS_TOP_BUILDDIR=.
>> tools/run-with-tmp-session-bus.sh make check' the services aren't
>> activated, despite having service files in the correct place, and
>> dbus-monitor doesn't show any activity on the bus.
>>
>> Finally, when the function was completing before I checked for replies
>> from the services the memleaks check reported 37 blocks unfreed, I can't
>> see where though.
>>
>> Any help is appreciated. I think all the patches to the .am and .in
>> files are correct, but I don't really know automake/conf so they may not
>> be.
>>
>> Matt
>>
>

-- 
Matthew Johnson
http://www.matthew.ath.cx/
-------------- next part --------------
diff -urN dbus-0.50/configure.in dbus-patched/configure.in
--- dbus-0.50/configure.in	2005-09-06 23:38:54.000000000 +0100
+++ dbus-patched/configure.in	2005-11-14 12:33:52.000000000 +0000
@@ -1311,6 +1311,8 @@
 test/data/valid-service-files/debug-shell-echo-success.service
 test/data/valid-service-files/debug-shell-echo-fail.service
 test/data/valid-service-files/debug-python.service
+test/data/valid-service-files/debug-readwrite.service
+test/data/valid-service-files/debug-readwritedispatch.service
 ])
 
 ### FIXME it's bizarre that have_qt and have_glib are used
diff -urN dbus-0.50/dbus/dbus-connection.c dbus-patched/dbus/dbus-connection.c
--- dbus-0.50/dbus/dbus-connection.c	2005-08-26 18:34:59.000000000 +0100
+++ dbus-patched/dbus/dbus-connection.c	2005-11-14 12:26:48.000000000 +0000
@@ -2836,11 +2836,11 @@
  * In this usage you would normally have set up a filter function to look
  * at each message as it is dispatched. The loop terminates when the last
  * message from the connection (the disconnected signal) is processed.
- * 
- * If there are messages to dispatch, this function will
- * dbus_connection_dispatch() once, and return. If there are no
- * messages to dispatch, this function will block until it can read or
- * write, then read or write, then return.
+ *
+ * If there are messages to dispatch and the dispatch flag is set, this
+ * function will dbus_connection_dispatch() once, and return. If there are no
+ * messages to dispatch, this function will block until it can read or write,
+ * then read or write, then return.
  *
  * The way to think of this function is that it either makes some sort
  * of progress, or it blocks.
@@ -2852,11 +2852,13 @@
  *
  * @param connection the connection
  * @param timeout_milliseconds max time to block or -1 for infinite
+ * @param dispatch dispatch new messages or leave them on the incoming queue
  * @returns #TRUE if the disconnect message has not been processed
  */
 dbus_bool_t
-dbus_connection_read_write_dispatch (DBusConnection *connection,
-                                     int             timeout_milliseconds)
+_dbus_connection_read_write_dispatch (DBusConnection *connection,
+                                     int             timeout_milliseconds, 
+                                     dbus_bool_t     dispatch)
 {
   DBusDispatchStatus dstatus;
   dbus_bool_t dispatched_disconnected;
@@ -2865,7 +2867,7 @@
   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
   dstatus = dbus_connection_get_dispatch_status (connection);
 
-  if (dstatus == DBUS_DISPATCH_DATA_REMAINS)
+  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
     {
       _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
       dbus_connection_dispatch (connection);
@@ -2898,6 +2900,68 @@
   return !dispatched_disconnected; /* TRUE if we have not processed disconnected */
 }
 
+
+/**
+ * This function is intended for use with applications that don't want
+ * to write a main loop and deal with #DBusWatch and #DBusTimeout. An
+ * example usage would be:
+ * 
+ * @code
+ *   while (dbus_connection_read_write_dispatch (connection, -1))
+ *     ; // empty loop body
+ * @endcode
+ * 
+ * In this usage you would normally have set up a filter function to look
+ * at each message as it is dispatched. The loop terminates when the last
+ * message from the connection (the disconnected signal) is processed.
+ * 
+ * If there are messages to dispatch, this function will
+ * dbus_connection_dispatch() once, and return. If there are no
+ * messages to dispatch, this function will block until it can read or
+ * write, then read or write, then return.
+ *
+ * The way to think of this function is that it either makes some sort
+ * of progress, or it blocks.
+ *
+ * The return value indicates whether the disconnect message has been
+ * processed, NOT whether the connection is connected. This is
+ * important because even after disconnecting, you want to process any
+ * messages you received prior to the disconnect.
+ *
+ * @param connection the connection
+ * @param timeout_milliseconds max time to block or -1 for infinite
+ * @returns #TRUE if the disconnect message has not been processed
+ */
+dbus_bool_t
+dbus_connection_read_write_dispatch (DBusConnection *connection,
+                                     int             timeout_milliseconds)
+{
+   return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
+}
+
+/** 
+ * This function is intended for use with applications that don't want to
+ * write a main loop and deal with #DBusWatch and #DBusTimeout.
+ * 
+ * If there are no messages to dispatch, this function will block until it can
+ * read or write, then read or write, then return.
+ *
+ * The return value indicates whether the disconnect message has been
+ * processed, NOT whether the connection is connected. This is important
+ * because even after disconnecting, you want to process any messages you
+ * received prior to the disconnect.
+ *
+ * @param connection the connection 
+ * @param timeout_milliseconds max time to block or -1 for infinite 
+ * @returns #TRUE if the disconnect message has not been processed
+ */
+dbus_bool_t 
+dbus_connection_read_write (DBusConnection *connection, 
+                            int             timeout_milliseconds) 
+{ 
+   return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
+}
+
 /**
  * Returns the first-received message from the incoming message queue,
  * leaving it in the queue. If the queue is empty, returns #NULL.
@@ -4672,4 +4736,123 @@
   return res;
 }
 
+
+#ifdef DBUS_BUILD_TESTS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "dbus-test.h"
+
+static dbus_bool_t
+check_readwrite (DBusConnection *connection, const char* service);
+
+#define TEST_READWRITE_SERVICE "org.freedesktop.DBus.TestSuiteReadWrite"
+#define TEST_READWRITEDISPATCH_SERVICE "org.freedesktop.DBus.TestSuiteReadWriteDispatch"
+
+dbus_bool_t
+_dbus_connection_test()
+{
+   DBusConnection* conn;
+   DBusError err;
+   char* address;
+
+   address = getenv ("DBUS_SESSION_BUS_ADDRESS");
+   if (address == NULL) {
+      _dbus_warn ("No Session Bus\n");
+      _dbus_exit(1);
+   }
+      
+   dbus_error_init(&err);
+   conn = dbus_connection_open_private(address, &err);
+
+   if (!check_readwrite (conn, TEST_READWRITE_SERVICE)) {
+      _dbus_warn ("Check ReadWrite failed\n");
+      _dbus_exit(1);
+   }
+
+   if (!check_readwrite (conn, TEST_READWRITEDISPATCH_SERVICE)) {
+      _dbus_warn ("Check ReadWriteDispatch failed\n");
+      _dbus_exit(1);
+   }
+
+   dbus_connection_close(conn);
+
+   return TRUE;
+}
+
+#define TEST_READWRITE_MESSAGE "ECHO"
+
+/* returns TRUE if the correct thing happens,
+ * but the correct thing may include OOM errors.
+ */
+static dbus_bool_t
+check_readwrite (DBusConnection *connection, const char* service)
+{
+  DBusMessage *message;
+  DBusPendingCall* pending;
+  DBusError err;
+  const char *text;
+
+  dbus_error_init(&err);
+
+  message = dbus_message_new_method_call (service,
+                                          "/org/freedesktop/TestSuite",
+                                          "org.freedesktop.TestSuite",
+                                          "ReadWriteTest");
+  
+  if (message == NULL)
+    return FALSE;
+
+  text = TEST_READWRITE_MESSAGE;
+
+  if (!dbus_message_append_args (message,
+                                 DBUS_TYPE_STRING, &text,
+                                 DBUS_TYPE_INVALID))
+    {
+      dbus_message_unref (message);
+      return FALSE;
+    }
+
+  if (!dbus_connection_send_with_reply (connection, message, &pending, -1))
+    {
+      dbus_message_unref (message);
+      return FALSE;
+    }
+
+  dbus_message_unref (message);
+  message = NULL;
+
+  dbus_pending_call_block(pending);
+      
+  message = dbus_pending_call_steal_reply(pending);
+  if (message == NULL)
+    {
+      _dbus_warn ("Failed to pop message! Should have been reply from ReadWriteTest message\n");
+      dbus_pending_call_unref(pending);
+      return FALSE;
+    }
+  dbus_pending_call_unref(pending);
+
+  if (!dbus_message_get_args (message, &err,
+           DBUS_TYPE_STRING, &text,
+           DBUS_TYPE_INVALID))
+  {
+      _dbus_warn ("Failed to get args! Should have been reply from ReadWriteTest message\n");
+     dbus_message_unref (message);
+     return FALSE;
+  }
+
+  _dbus_warn ("Got ReadWrite Test Reply: %s\n", text);
+
+  if (0 != strncmp(text, TEST_READWRITE_MESSAGE, strlen(TEST_READWRITE_MESSAGE))) {
+      _dbus_warn ("Arg was incorrect! Should have been reply from ReadWriteTest message\n");
+     dbus_message_unref (message);
+     return FALSE;
+  }
+
+  dbus_message_unref (message);
+
+  return TRUE;      
+}
+#endif
 /** @} */
diff -urN dbus-0.50/dbus/dbus-connection.h dbus-patched/dbus/dbus-connection.h
--- dbus-0.50/dbus/dbus-connection.h	2005-06-06 19:55:22.000000000 +0100
+++ dbus-patched/dbus/dbus-connection.h	2005-11-14 11:02:55.000000000 +0000
@@ -102,6 +102,8 @@
 void               dbus_connection_flush                        (DBusConnection             *connection);
 dbus_bool_t        dbus_connection_read_write_dispatch          (DBusConnection             *connection,
                                                                  int                         timeout_milliseconds);
+dbus_bool_t        dbus_connection_read_write                   (DBusConnection             *connection,
+                                                                 int                         timeout_milliseconds);
 DBusMessage*       dbus_connection_borrow_message               (DBusConnection             *connection);
 void               dbus_connection_return_message               (DBusConnection             *connection,
                                                                  DBusMessage                *message);
diff -urN dbus-0.50/dbus/dbus-test.c dbus-patched/dbus/dbus-test.c
--- dbus-0.50/dbus/dbus-test.c	2005-02-24 16:03:56.000000000 +0000
+++ dbus-patched/dbus/dbus-test.c	2005-11-14 11:28:16.000000000 +0000
@@ -120,6 +120,8 @@
 
   run_test ("server", specific_test, _dbus_server_test);
 
+  run_test ("connections", specific_test, _dbus_connection_test);
+
   run_test ("object-tree", specific_test, _dbus_object_tree_test);
 
   run_test ("signature", specific_test, _dbus_signature_test);
diff -urN dbus-0.50/dbus/dbus-test.h dbus-patched/dbus/dbus-test.h
--- dbus-0.50/dbus/dbus-test.h	2005-02-24 16:03:56.000000000 +0000
+++ dbus-patched/dbus/dbus-test.h	2005-11-14 11:01:30.000000000 +0000
@@ -41,6 +41,7 @@
 dbus_bool_t _dbus_string_test            (void);
 dbus_bool_t _dbus_address_test           (void);
 dbus_bool_t _dbus_server_test            (void);
+dbus_bool_t _dbus_connection_test        (void);
 dbus_bool_t _dbus_message_test           (const char *test_data_dir);
 dbus_bool_t _dbus_auth_test              (const char *test_data_dir);
 dbus_bool_t _dbus_md5_test               (void);
diff -urN dbus-0.50/test/data/valid-service-files/debug-readwritedispatch.service.in dbus-patched/test/data/valid-service-files/debug-readwritedispatch.service.in
--- dbus-0.50/test/data/valid-service-files/debug-readwritedispatch.service.in	1970-01-01 01:00:00.000000000 +0100
+++ dbus-patched/test/data/valid-service-files/debug-readwritedispatch.service.in	2005-11-14 12:31:24.000000000 +0000
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.DBus.TestSuiteReadWriteDispatch
+Exec=@TEST_READWRITE_BINARY@
diff -urN dbus-0.50/test/data/valid-service-files/debug-readwrite.service.in dbus-patched/test/data/valid-service-files/debug-readwrite.service.in
--- dbus-0.50/test/data/valid-service-files/debug-readwrite.service.in	1970-01-01 01:00:00.000000000 +0100
+++ dbus-patched/test/data/valid-service-files/debug-readwrite.service.in	2005-11-09 14:19:46.000000000 +0000
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.DBus.TestSuiteReadWrite
+Exec=@TEST_READWRITE_BINARY@
diff -urN dbus-0.50/test/Makefile.am dbus-patched/test/Makefile.am
--- dbus-0.50/test/Makefile.am	2005-08-25 01:20:41.000000000 +0100
+++ dbus-patched/test/Makefile.am	2005-11-09 12:28:26.000000000 +0000
@@ -14,7 +14,7 @@
 
 if DBUS_BUILD_TESTS
 ## break-loader removed for now
-TEST_BINARIES=test-service test-shell-service shell-test spawn-test test-segfault test-exit test-sleep-forever
+TEST_BINARIES=test-readwrite test-service test-shell-service shell-test spawn-test test-segfault test-exit test-sleep-forever
 
 #enable stand alone make check test
 TESTS=shell-test
@@ -52,6 +52,8 @@
 
 test_exit_SOURCES =				\
 	test-exit.c
+test_readwrite_SOURCES =				\
+	test-readwrite.c
 
 test_segfault_SOURCES =				\
 	test-segfault.c
diff -urN dbus-0.50/test/Makefile.in dbus-patched/test/Makefile.in
--- dbus-0.50/test/Makefile.in	2005-09-06 23:45:16.000000000 +0100
+++ dbus-patched/test/Makefile.in	2005-11-09 12:33:28.000000000 +0000
@@ -53,6 +53,7 @@
 @DBUS_BUILD_TESTS_TRUE@	shell-test$(EXEEXT) spawn-test$(EXEEXT) \
 @DBUS_BUILD_TESTS_TRUE@	test-segfault$(EXEEXT) \
 @DBUS_BUILD_TESTS_TRUE@	test-exit$(EXEEXT) \
+ at DBUS_BUILD_TESTS_TRUE@	test-readwrite$(EXEEXT) \
 @DBUS_BUILD_TESTS_TRUE@	test-sleep-forever$(EXEEXT)
 @DBUS_GCOV_ENABLED_TRUE at am__EXEEXT_2 = decode-gcov$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
@@ -84,6 +85,9 @@
 am_test_sleep_forever_OBJECTS = test-sleep-forever.$(OBJEXT)
 test_sleep_forever_OBJECTS = $(am_test_sleep_forever_OBJECTS)
 test_sleep_forever_LDADD = $(LDADD)
+am_test_readwrite_OBJECTS = test-readwrite.$(OBJEXT)
+test_readwrite_OBJECTS = $(am_test_readwrite_OBJECTS)
+test_readwrite_LDADD = $(LDADD)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -98,10 +102,12 @@
 SOURCES = $(decode_gcov_SOURCES) $(shell_test_SOURCES) \
 	$(spawn_test_SOURCES) $(test_exit_SOURCES) \
 	$(test_segfault_SOURCES) $(test_service_SOURCES) \
+	$(test_readwrite_SOURCES) \
 	$(test_shell_service_SOURCES) $(test_sleep_forever_SOURCES)
 DIST_SOURCES = $(decode_gcov_SOURCES) $(shell_test_SOURCES) \
 	$(spawn_test_SOURCES) $(test_exit_SOURCES) \
 	$(test_segfault_SOURCES) $(test_service_SOURCES) \
+	$(test_readwrite_SOURCES) \
 	$(test_shell_service_SOURCES) $(test_sleep_forever_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
 	html-recursive info-recursive install-data-recursive \
@@ -361,7 +367,7 @@
 DIST_SUBDIRS = glib python
 INCLUDES = -I$(top_srcdir) $(DBUS_TEST_CFLAGS) 
 @DBUS_BUILD_TESTS_FALSE at TEST_BINARIES = 
- at DBUS_BUILD_TESTS_TRUE@TEST_BINARIES = test-service test-shell-service shell-test spawn-test test-segfault test-exit test-sleep-forever
+ at DBUS_BUILD_TESTS_TRUE@TEST_BINARIES = test-service test-shell-service shell-test spawn-test test-segfault test-exit test-sleep-forever test-readwrite
 @DBUS_BUILD_TESTS_FALSE at TESTS = 
 
 #enable stand alone make check test
@@ -383,6 +389,9 @@
 
 spawn_test_SOURCES = \
 	spawn-test.c
+	
+test_readwrite_SOURCES = \
+	test-readwrite.c
 
 test_exit_SOURCES = \
 	test-exit.c
@@ -398,6 +407,7 @@
 
 TEST_LIBS = $(DBUS_TEST_LIBS) $(top_builddir)/dbus/libdbus-convenience.la
 test_service_LDADD = $(TEST_LIBS)
+test_readwrite_LDADD = $(TEST_LIBS)
 test_shell_service_LDADD = $(TEST_LIBS)
 shell_test_LDADD = $(TEST_LIBS)
 spawn_test_LDADD = $(TEST_LIBS)
@@ -486,6 +496,9 @@
 test-sleep-forever$(EXEEXT): $(test_sleep_forever_OBJECTS) $(test_sleep_forever_DEPENDENCIES) 
 	@rm -f test-sleep-forever$(EXEEXT)
 	$(LINK) $(test_sleep_forever_LDFLAGS) $(test_sleep_forever_OBJECTS) $(test_sleep_forever_LDADD) $(LIBS)
+test-readwrite$(EXEEXT): $(test_readwrite_OBJECTS) $(test_readwrite_DEPENDENCIES) 
+	@rm -f test-readwrite$(EXEEXT)
+	$(LINK) $(test_readwrite_LDFLAGS) $(test_readwrite_OBJECTS) $(test_readwrite_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -499,6 +512,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-exit.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-segfault.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-service.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-readwrite.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-shell-service.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-sleep-forever.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test-utils.Po at am__quote@
diff -urN dbus-0.50/test/test-readwrite.c dbus-patched/test/test-readwrite.c
--- dbus-0.50/test/test-readwrite.c	1970-01-01 01:00:00.000000000 +0100
+++ dbus-patched/test/test-readwrite.c	2005-11-14 12:18:38.000000000 +0000
@@ -0,0 +1,107 @@
+#include <dbus/dbus.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+void reply_to_method_call(DBusMessage* msg, DBusConnection* conn)
+{
+
+   DBusMessage* reply;
+   DBusMessageIter args;
+   dbus_uint32_t serial = 0;
+   char* param = "";
+   fprintf(stderr, "Replying\n");
+
+   // read the arguments
+   if (!dbus_message_iter_init(msg, &args))
+      fprintf(stderr, "Message has no arguments!\n"); 
+   else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) 
+      fprintf(stderr, "Argument is not string!\n"); 
+   else 
+      dbus_message_iter_get_basic(&args, &param);
+
+   fprintf(stderr, "Message: %s\n", param);
+   // create a reply from the message
+   reply = dbus_message_new_method_return(msg);
+
+   // add the arguments to the reply
+   dbus_message_iter_init_append(reply, &args);
+   if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) { 
+      fprintf(stderr, "Out Of Memory!\n"); 
+      exit(1);
+   }
+
+   fprintf(stderr, "Sending...");
+   // send the reply && flush the connection
+   if (!dbus_connection_send(conn, reply, &serial)) {
+      fprintf(stderr, "Out Of Memory!\n"); 
+      exit(1);
+   }
+   dbus_connection_flush(conn);
+   fprintf(stderr, "sedone\n");
+
+   // free the reply
+   dbus_message_unref(reply);
+}
+
+void main(int argc, char** argv)
+{
+   DBusMessage* msg;
+   DBusConnection* conn;
+   DBusError err;
+   int ret;
+
+   fprintf(stderr, "Listening for Ping\n");
+
+   // initialise the error
+   dbus_error_init(&err);
+   
+   // connect to the bus and check for errors
+   conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
+   if (dbus_error_is_set(&err)) { 
+      fprintf(stderr, "Connection Error (%s)\n", err.message); 
+      dbus_error_free(&err); 
+   }
+   if (NULL == conn) {
+      fprintf(stderr, "Connection Null\n"); 
+      exit(1); 
+   }
+   
+   // request our name on the bus and check for errors
+   ret = dbus_bus_request_name(conn, "org.freedesktop.DBus.TestSuiteReadWrite", DBUS_NAME_FLAG_REPLACE_EXISTING | 
+                                                               DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &err);
+   if (dbus_error_is_set(&err)) { 
+      fprintf(stderr, "Name Error (%s)\n", err.message); 
+      dbus_error_free(&err);
+      exit(1); 
+   }
+   /*if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 
+      fprintf(stderr, "Not Primary Owner (%d)\n", ret);
+      exit(1); 
+   }*/
+
+   while (true) {
+   fprintf(stderr, "Blocking on readwrite...");
+   dbus_connection_read_write(conn, -1);
+   fprintf(stderr, "rwdone\n");
+   msg = dbus_connection_pop_message(conn);
+
+   // check this is a method call for the right interface & method
+   if (dbus_message_is_method_call(msg, "test.readwrite.Type", "Method")) {
+      reply_to_method_call(msg, conn);
+      break;
+   } else
+   fprintf(stderr, "Not A Message\n");
+
+   // free the message
+   dbus_message_unref(msg);
+   }
+
+   // close the connection
+   dbus_connection_close(conn);
+}
+


More information about the dbus mailing list