C-API Examples

Ralf Habacker ralf.habacker at freenet.de
Wed May 10 15:27:20 PDT 2006


Robert McQueen schrieb:
> Ralf Habacker wrote:
>   
>> In this list it was announced, that the bindings. probably the glib
>> binding too, will be separated from the core. Unfortunally dbus-monitor
>> depends on the glib binding, which means, that either dbus-monitor has
>> to be moved into the glib binding or dbus-monitor get's a dbus based
>> main loop.
>>     
>
> Unless someone desperately wants to patch it, I'd move it into
> dbus-glib, along with the dbus-viewer and other similar stuff.
>
>   
I've tried, but have some problems.

I have got running dbus-monitor.c with the  following function

void my_dbus_loop_run(DBusLoop * loop)
{
    DBusConnection *conn = _dbus_list_pop_first (&loop->need_dispatch);

  _dbus_verbose ("  %d connections to dispatch\n", _dbus_list_get_length 
(&loop->need_dispatch));
  _dbus_loop_ref (loop);

   // loop listening for messages being emmitted
   while (1) {

      // non blocking read of the next available message
        dbus_connection_read_write(conn, 0);
        while(dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS)
            ;
        Sleep(1);
   }
  _dbus_loop_unref (loop);

}

static DBusHandlerResult
filter_func (DBusConnection     *connection,
             DBusMessage        *message,
             void               *user_data)
{
  print_message (message, FALSE);
 
  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    exit (0);
 
  /* Conceptually we want this to be
   * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
   * some problems.  See bug 1719.
   */
  return DBUS_HANDLER_RESULT_HANDLED;
}


int main
...
     DBusLoop * loop;
     loop = _dbus_loop_new();
     connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
    ... set some filters ...
    _dbus_loop_queue_dispatch(loop,connection);
     dbus_connection_add_filter (connection, filter_func, NULL, NULL))
     my_dbus_loop_run(loop);

This works like expected. The only issue I had was the disconnecting 
does not work.  The filter_func looks  like this:

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    exit (0);

and DBUS_INTERFACE_LOCAL is set to "org.freedesktop.DBus.Local".

But when I send
    bin\dbus-send --type=signal --dest=org.freedesktop.DBus /  
org.freedesktop.DBus.Local.Disconnect
the result looks like
    Error org.freedesktop.DBus.Error.NoReply: No reply within specified time
Then I changed the interface to org.freedesktop.DBus and send
    bin\dbus-send --type=signal --dest=org.freedesktop.DBus /  
org.freedesktop.DBus.Disconnect

this works. Any idea what't wrong ?

Another solution i got with

void  my_dbus_loop_run(DBusLoop * loop)
{
   DBusMessage* msg;
     DBusConnection *conn = _dbus_list_pop_first (&loop->need_dispatch);

  _dbus_verbose ("  %d connections to dispatch\n", _dbus_list_get_length 
(&loop->need_dispatch));
  _dbus_loop_ref (loop);

   // loop listening for signals being emmitted
   while (1) {

      // non blocking read of the next available message
      dbus_connection_read_write(conn, 0);
      msg = dbus_connection_pop_message(conn);

      // loop again if we haven't read a message
      if (NULL == msg) {
         sleep(1);
         continue;
      }
      printf("message :sender %s\n type %d\n dest %s\n path %s\n 
interface %s\n member %s\n signature %s\n",
          dbus_message_get_sender(msg),
          dbus_message_get_type(msg),
          dbus_message_get_destination(msg),
          dbus_message_get_path(msg),
          dbus_message_get_interface(msg),
          dbus_message_get_member(msg),
          dbus_message_get_signature(msg)
          );

      // free the message
      dbus_message_unref(msg);
    }
}

unfortunally this does not print the results, probably because the 
messages  are not  dispatched isn't it ?

int main
...
     DBusLoop * loop;
     loop = _dbus_loop_new();
     connection = dbus_bus_get (DBUS_BUS_SESSION,&error);
    _dbus_loop_queue_dispatch(loop,connection);
     my_dbus_loop_run(loop);


BTW: Using the function _dbus_loop_run() from dbus-mainloop.c does not 
work as expected. I have  taken a look into dbus_loop_run, which calls 
dbus_loop_iterate() but I do not understand what there happens  real.  I 
saw that  this function is used for example for the 
test/test-shell-service.c but this seems to be another context.


Regards
 Ralf



More information about the dbus mailing list