[pulseaudio-discuss] [PATCH v2 2/9] dbus: Track the default sink and source with hooks

David Henningsson david.henningsson at canonical.com
Mon Mar 18 06:00:37 PDT 2013


On 02/20/2013 07:23 PM, Tanu Kaskinen wrote:
> ---
>   src/modules/dbus/iface-core.c |  173 +++++++++++++++++------------------------
>   1 file changed, 72 insertions(+), 101 deletions(-)
>
> diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
> index a9716bc..4621726 100644
> --- a/src/modules/dbus/iface-core.c
> +++ b/src/modules/dbus/iface-core.c
> @@ -108,9 +108,8 @@ struct pa_dbusiface_core {
>       pa_hashmap *modules;
>       pa_hashmap *clients;
>
> -    pa_sink *fallback_sink;
> -    pa_source *fallback_source;
> -
> +    pa_hook_slot *default_sink_changed_slot;
> +    pa_hook_slot *default_source_changed_slot;
>       pa_hook_slot *sink_put_slot;
>       pa_hook_slot *sink_unlink_slot;
>       pa_hook_slot *source_put_slot;
> @@ -677,13 +676,12 @@ static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi
>       pa_assert(msg);
>       pa_assert(c);
>
> -    if (!c->fallback_sink) {
> -        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
> -                           "There are no sinks, and therefore no fallback sink either.");
> +    if (!c->core->default_sink) {
> +        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "No fallback sink set.");
>           return;
>       }

Is there a reason for using core->default_sink instead of 
pa_namereg_get_default_sink?

E g, the native protocol (e g pactl stat) uses 
pa_namereg_get_default_sink instead of the direct pointer.

As for the other dbus patches (and "core: Add hooks for default device 
changes"), I looked them briefly through and saw nothing to remark on. 
With the disclaimer that I don't know the dbus stuff very well, but I'd 
just say it's a very welcome fix, if it fixes the occasional crashes on 
device unplug.

>
> -    pa_assert_se((fallback_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))));
> +    pa_assert_se((fallback_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->core->default_sink->index))));
>       object_path = pa_dbusiface_device_get_path(fallback_sink);
>
>       pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
> @@ -699,12 +697,6 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBu
>       pa_assert(iter);
>       pa_assert(c);
>
> -    if (!c->fallback_sink) {
> -        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
> -                           "There are no sinks, and therefore no fallback sink either.");
> -        return;
> -    }
> -
>       dbus_message_iter_get_basic(iter, &object_path);
>
>       if (!(fallback_sink = pa_hashmap_get(c->sinks_by_path, object_path))) {
> @@ -765,13 +757,12 @@ static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, v
>       pa_assert(msg);
>       pa_assert(c);
>
> -    if (!c->fallback_source) {
> -        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
> -                           "There are no sources, and therefore no fallback source either.");
> +    if (!c->core->default_source) {
> +        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "No fallback source set.");
>           return;
>       }
>
> -    pa_assert_se((fallback_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index))));
> +    pa_assert_se((fallback_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->core->default_source->index))));
>       object_path = pa_dbusiface_device_get_path(fallback_source);
>
>       pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
> @@ -787,12 +778,6 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, D
>       pa_assert(iter);
>       pa_assert(c);
>
> -    if (!c->fallback_source) {
> -        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
> -                           "There are no sources, and therefore no fallback source either.");
> -        return;
> -    }
> -
>       dbus_message_iter_get_basic(iter, &object_path);
>
>       if (!(fallback_source = pa_hashmap_get(c->sources_by_path, object_path))) {
> @@ -1094,13 +1079,12 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
>       alternate_sample_rate = c->core->alternate_sample_rate;
>       cards = get_cards(c, &n_cards);
>       sinks = get_sinks(c, &n_sinks);
> -    fallback_sink = c->fallback_sink
> -                    ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)))
> +    fallback_sink = c->core->default_sink
> +                    ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->core->default_sink->index)))
>                       : NULL;
>       sources = get_sources(c, &n_sources);
> -    fallback_source = c->fallback_source
> -                      ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index,
> -                                                                    PA_UINT32_TO_PTR(c->fallback_source->index)))
> +    fallback_source = c->core->default_source
> +                      ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->core->default_source->index)))
>                         : NULL;
>       playback_streams = get_playback_streams(c, &n_playback_streams);
>       record_streams = get_record_streams(c, &n_record_streams);
> @@ -1573,77 +1557,16 @@ static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *
>   static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
>       pa_dbusiface_core *c = userdata;
>       pa_dbusiface_card *card_iface = NULL;
> -    pa_dbusiface_device *device_iface = NULL;
>       pa_dbusiface_stream *stream_iface = NULL;
>       pa_dbusiface_sample *sample_iface = NULL;
>       pa_dbusiface_module *module_iface = NULL;
>       pa_dbusiface_client *client_iface = NULL;
>       DBusMessage *signal_msg = NULL;
>       const char *object_path = NULL;
> -    pa_sink *new_fallback_sink = NULL;
> -    pa_source *new_fallback_source = NULL;
>
>       pa_assert(c);
>
>       switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
> -        case PA_SUBSCRIPTION_EVENT_SERVER:
> -            new_fallback_sink = pa_namereg_get_default_sink(core);
> -            new_fallback_source = pa_namereg_get_default_source(core);
> -
> -            if (c->fallback_sink != new_fallback_sink) {
> -                if (c->fallback_sink)
> -                    pa_sink_unref(c->fallback_sink);
> -                c->fallback_sink = new_fallback_sink ? pa_sink_ref(new_fallback_sink) : NULL;
> -
> -                if (c->fallback_sink) {
> -                    pa_assert_se(device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)));
> -                    object_path = pa_dbusiface_device_get_path(device_iface);
> -
> -                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> -								       PA_DBUS_CORE_INTERFACE,
> -								       signals[SIGNAL_FALLBACK_SINK_UPDATED].name)));
> -                    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
> -                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
> -                    dbus_message_unref(signal_msg);
> -                    signal_msg = NULL;
> -
> -                } else {
> -                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> -                                                                       PA_DBUS_CORE_INTERFACE,
> -                                                                       signals[SIGNAL_FALLBACK_SINK_UNSET].name)));
> -                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
> -                    dbus_message_unref(signal_msg);
> -                    signal_msg = NULL;
> -                }
> -            }
> -
> -            if (c->fallback_source != new_fallback_source) {
> -                if (c->fallback_source)
> -                    pa_source_unref(c->fallback_source);
> -                c->fallback_source = new_fallback_source ? pa_source_ref(new_fallback_source) : NULL;
> -
> -                if (c->fallback_source) {
> -                    pa_assert_se(device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)));
> -                    object_path = pa_dbusiface_device_get_path(device_iface);
> -
> -                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> -								       PA_DBUS_CORE_INTERFACE,
> -								       signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name)));
> -                    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
> -                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
> -                    dbus_message_unref(signal_msg);
> -                    signal_msg = NULL;
> -
> -                } else {
> -                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> -                                                                       PA_DBUS_CORE_INTERFACE,
> -                                                                       signals[SIGNAL_FALLBACK_SOURCE_UNSET].name)));
> -                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
> -                    dbus_message_unref(signal_msg);
> -                    signal_msg = NULL;
> -                }
> -            }
> -            break;
>
>           case PA_SUBSCRIPTION_EVENT_CARD:
>               if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
> @@ -1856,6 +1779,62 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
>       }
>   }
>
> +static pa_hook_result_t default_sink_changed_cb(pa_core *core, pa_sink *sink, pa_dbusiface_core *core_iface) {
> +    const char *object_path = NULL;
> +    DBusMessage *signal_msg = NULL;
> +
> +    pa_assert(core);
> +    pa_assert(core_iface);
> +
> +    if (sink) {
> +        pa_dbusiface_device *device_iface;
> +
> +        pa_assert_se(device_iface = pa_hashmap_get(core_iface->sinks_by_index, PA_UINT32_TO_PTR(sink->index)));
> +        object_path = pa_dbusiface_device_get_path(device_iface);
> +        pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> +                                                           PA_DBUS_CORE_INTERFACE,
> +                                                           signals[SIGNAL_FALLBACK_SINK_UPDATED].name)));
> +        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
> +
> +    } else
> +        pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> +                                                           PA_DBUS_CORE_INTERFACE,
> +                                                           signals[SIGNAL_FALLBACK_SINK_UNSET].name)));
> +
> +    pa_dbus_protocol_send_signal(core_iface->dbus_protocol, signal_msg);
> +    dbus_message_unref(signal_msg);
> +
> +    return PA_HOOK_OK;
> +}
> +
> +static pa_hook_result_t default_source_changed_cb(pa_core *core, pa_source *source, pa_dbusiface_core *core_iface) {
> +    const char *object_path = NULL;
> +    DBusMessage *signal_msg = NULL;
> +
> +    pa_assert(core);
> +    pa_assert(core_iface);
> +
> +    if (source) {
> +        pa_dbusiface_device *device_iface;
> +
> +        pa_assert_se(device_iface = pa_hashmap_get(core_iface->sources_by_index, PA_UINT32_TO_PTR(source->index)));
> +        object_path = pa_dbusiface_device_get_path(device_iface);
> +        pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> +                                                           PA_DBUS_CORE_INTERFACE,
> +                                                           signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name)));
> +        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
> +
> +    } else
> +        pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
> +                                                           PA_DBUS_CORE_INTERFACE,
> +                                                           signals[SIGNAL_FALLBACK_SOURCE_UNSET].name)));
> +
> +    pa_dbus_protocol_send_signal(core_iface->dbus_protocol, signal_msg);
> +    dbus_message_unref(signal_msg);
> +
> +    return PA_HOOK_OK;
> +}
> +
>   static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *slot_data) {
>       pa_dbusiface_core *c = slot_data;
>       pa_sink *s = call_data;
> @@ -2031,8 +2010,8 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
>       c->samples = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
>       c->modules = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
>       c->clients = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
> -    c->fallback_sink = pa_namereg_get_default_sink(core);
> -    c->fallback_source = pa_namereg_get_default_source(core);
> +    c->default_sink_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) default_sink_changed_cb, c);
> +    c->default_source_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) default_source_changed_cb, c);
>       c->sink_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, sink_put_cb, c);
>       c->sink_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL, sink_unlink_cb, c);
>       c->source_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, source_put_cb, c);
> @@ -2049,11 +2028,6 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
>                                                                      c);
>       c->memstats = pa_dbusiface_memstats_new(c, core);
>
> -    if (c->fallback_sink)
> -        pa_sink_ref(c->fallback_sink);
> -    if (c->fallback_source)
> -        pa_source_ref(c->fallback_source);
> -
>       PA_IDXSET_FOREACH(card, core->cards, idx)
>           pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(c, card));
>
> @@ -2113,13 +2087,10 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) {
>       pa_hook_slot_free(c->source_unlink_slot);
>       pa_hook_slot_free(c->extension_registered_slot);
>       pa_hook_slot_free(c->extension_unregistered_slot);
> +    pa_hook_slot_free(c->default_source_changed_slot);
> +    pa_hook_slot_free(c->default_sink_changed_slot);
>       pa_dbusiface_memstats_free(c->memstats);
>
> -    if (c->fallback_sink)
> -        pa_sink_unref(c->fallback_sink);
> -    if (c->fallback_source)
> -        pa_source_unref(c->fallback_source);
> -
>       pa_dbus_protocol_unref(c->dbus_protocol);
>
>       pa_xfree(c);
>



-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic


More information about the pulseaudio-discuss mailing list