[pulseaudio-discuss] Receiving signals from server in C

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Tue Jun 17 05:34:53 PDT 2014


On Tue, 2014-06-17 at 13:54 +0200, Greg Knoll wrote:
> On Tue, Jun 17, 2014 at 10:31 AM, Tanu Kaskinen
> <tanu.kaskinen at linux.intel.com> wrote:
> > On Fri, 2014-06-13 at 17:17 +0200, Greg Knoll wrote:
> >> I think first it would be good to know that I'm correctly registering
> >> with ListenForSignal.  First I use
> >>
> >>    conn = dbus_connection_open(serverAddress, &err);
> >>
> >> to get a connection to PulseAudio.  Then I call the message:
> >>
> >>     msg = dbus_message_new_method_call(
> >>
> >>             "org.PulseAudio1",             //Destination
> >>
> >>             "/org/pulseaudio/core1",     //Object path to call on
> >>
> >>             "org.PulseAudio.Core1",     //Interface to call on
> >>
> >>             "ListenForSignal");             //Method
> >>
> >>
> >>
> >>     //Add arguments: s, []
> >>
> >>     dbus_message_iter_init_append(msg, &msgIter);
> >>
> >>
> >>         //string
> >>
> >>         dbus_message_iter_append_basic(&msgIter, DBUS_TYPE_STRING,&signalName);
> >>
> >>
> >>         //empty array to listen to all
> >>
> >>         dbus_message_iter_open_container(&msgIter,DBUS_TYPE_ARRAY,"o",&arrayIter);
> >>
> >>         dbus_message_iter_close_container(&msgIter, &arrayIter);
> >>
> >>
> >>     //call dbus function
> >>
> >>     debug_print("   >...Listening for signal %s...\n",signalName);
> >>
> >>     dbus_connection_send_with_reply_and_block (conn, msg, -1, &err);
> >>
> >> with signalName = "org.PulseAudio.Core1.NewModule"
> >>
> >> Is this correct if I want to be notified when all new modules are loaded?
> >
> > Yes, looks correct.
> >
> >> If so, I then call dbus_connection_pop_message on the private
> >> connection in the main loop.
> >
> > How do you wait for incoming messages?
> >
> > Typically you shouldn't call dbus_connection_pop_message() (even the
> > documentation of that function says that). If you have a main loop, you
> > should integrate the DBusConnection with the main loop. If you don't
> > have a main loop in your program, you can use
> > dbus_connection_read_write_dispatch().
> >
> >>Do I need to add a match?
> >
> > As already discussed in this thread: no, you don't need to add a match.
> >
> > --
> > Tanu
> >
> 
> Thank you for the reply and I apologize for accidentally top posting again.
> 
> I do have a main loop, but not a glib main loop.  I am running a
> while() loop in a QtThread.

If you use Qt, why don't you use QtDBus? In the past (years ago) QtDBus
didn't support peer-to-peer connections, but I believe that has been
fixed.

> I use
> dbus_connection_read_write_dispatch() already in this loop for the
> system bus, and successfully use dbus_connection_pop_message() for
> system bus messages.

I don't understand what you use pop_message() for. Dispatching means
that received messages are processed, so if you call
read_write_dispatch() and you have set up a filter function and/or
registered object paths for receiving method calls, there should be no
need to manually steal messages from the incoming queue.

> I tried the same method (without using
> dbus_connection_pop_message() as you suggested) for the PA connection,
> and then used dbus_connection_add_filter() to add a
> DBusHandleMessageFunction.  I still get nothing.

"...and then used dbus_connection_add_filter()" sounds a bit like you
call add_filter() *after* calling read_write_dispatch(), but that's
probably not what you're doing. So if you're setting the filter first
and then processing incoming messages with read_write_dispatch(), that
should result in getting all received messages in the filter function
(except those that are received during blocking method calls). I don't
have good ideas about what might be wrong.

What if you pass an empty string as the signal name to ListenForSignal,
and then you do stuff like load modules or change the volume or
whatever? Do you get no signals at all? (Empty signal name means
listening for all signals.)

> What exactly do you mean by integrating the DBusConnection with the
> main loop?  Do you mean registering watch functions
> (dbus_connection_set_watch_functions()) and object paths
> (dbus_connection_register_object_path), etc?

I mean registering the watch functions and some other functions. See for
example pa_dbus_wrap_connection_new_from_existing, which integrates a
DBusConnection with PulseAudio's main loop:
http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/src/pulsecore/dbus-util.c#n297

If you use Qt, there may be utilities for integrating a DBusConnection
with the Qt main loop, but there's not much point in creating
DBusConnection objects manually in Qt when there's QDBusConnection
available.

Object paths aren't really relevant here. You should register object
paths if you expose objects on D-Bus, but you don't need that just for
receiving signals.

-- 
Tanu



More information about the pulseaudio-discuss mailing list