Daniel Falk
Daniel Falk

Reputation: 522

Low Level DBus C API main loop

When trying to use a callback function for a DBus reply I get stuck on creating a good/well working main loop.

What I want to do is simple, make a DBus call and specify a function which should be called when the reply comes. This is because I do not want to block my thread for the whole time until a reply has been calculated and arrived.

I first use dbus_connection_send_with_reply(..) to get a DBusPendingCall, then i specify a callback function using dbus_pending_call_set_notify(..). Before doing this, when connecting to the bus, I have started another thread which should wait for a response and call the callback functions. I have found no examples at all and no very good documentation of how I should design a dbus main-loop like this. I have tried:

// Main dbus loop handling data transfer and callbacks..
void *dbus_main(void *args)
{
    my_dbus dbus = (my_dbus)args;

    while (MY_DBUS_STATUS_STOPPING != dbus->status
            && dbus_connection_read_write_dispatch(dbus->conn, -1))
        ;

    return 0;
}

// Start the dbus main loop in a new thread
void dbus_main_start(my_dbus dbus) {
    if (!pthread_create(&dbus->th, NULL, dbus_main, dbus)) {
        // PRINT ERROR
    }
}

My problem is two things:

So anyone who has an example of using the low-level dbus api together with async methods, ie not using _block(..)??

Upvotes: 3

Views: 2295

Answers (2)

User55412
User55412

Reputation: 940

You can create a simple DBus application as follows...

To setup a server to handle incoming messages, call dbus_connection_register_object_path passing in a VTable containing function pointers to handle the messages. Such as:

{ .unregister_function = UnregisteredMessage, .message_function = ServiceMessage }

To send a new message, call dbus_connection_send_with_reply and then dbus_pending_call_set_notify to associate a callback function to handle the reply.

Next you will need to service DBus. This can be done in a separate thread or by calling periodically with non-blocking calls in the same thread, as shown below:

/* Non-blocking read of the next available message */
dbus_connection_read_write ( MyDBusConnection, 0 ) ;

while ( dbus_connection_get_dispatch_status ( MyDBusConnection ) == DBUS_DISPATCH_DATA_REMAINS )
{
   dbus_connection_dispatch ( MyDBusConnection ) ;
}

There are some good example of using the DBUS C API here: http://www.matthew.ath.cx/misc/dbus

Upvotes: 1

Philip Withnall
Philip Withnall

Reputation: 5733

It is highly recommended that you use a D-Bus library other than libdbus, as libdbus is fiddly to use correctly, as you are finding. If possible, use GDBus or QtDBus instead, as they are much higher-level bindings which are easier to use. If you need a lower-level binding, sd-bus is more modern than libdbus.

If you use GDBus, you can use GMainLoop to implement a main loop. If you use sd-bus, you can use sd-event.

Upvotes: 0

Related Questions