]> code.delx.au - pulseaudio/commitdiff
device-manager: Don't try to use unlinked devices
authorTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Sun, 26 Jan 2014 18:13:50 +0000 (20:13 +0200)
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Sun, 26 Jan 2014 19:20:31 +0000 (21:20 +0200)
This fixes an assertion crash:

[pulseaudio] source.c: Assertion 'PA_SOURCE_IS_LINKED(s->state)' failed at pulsecore/source.c:734, function pa_source_update_status(). Aborting.

The crash happened when a Bluetooth headset profile was changed from
a2dp to hsp. During the profile change three devices are created:
a sink, a monitor source for the sink, and a regular source. First
pa_sink/source_new() are called for each device, and that puts the
devices to u->core->sinks/sources. Then, pa_sink_put() is called for
the sink, and that in turn calls pa_source_put() for the source. At
that point module-device-manager decides to reroute all source
outputs. The non-monitor source that the Bluetooth card created hasn't
been linked yet at this stage, because it will only be linked after
the sink and the monitor source have been linked. So,
module-device-manager should take into account during the rerouting
that not all sinks and sources are necessarily linked. This patch does
that.

Reported-By: Iskren Hadzhinedev <i.hadzhinedev@gmail.com>
src/modules/module-device-manager.c

index 9df3d8e2e55159792b43ef5368e2bf535bc6a78e..d86c158d1c6c5eeed7df6c619e9df628aca8bc79 100644 (file)
@@ -605,6 +605,8 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
                             PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
                                 if ((pa_sink*) ignore_device == sink)
                                     continue;
+                                if (!PA_SINK_IS_LINKED(sink->state))
+                                    continue;
                                 if (pa_streq(sink->name, device_name)) {
                                     found = true;
                                     idx = sink->index; /* Is this needed? */
@@ -617,6 +619,8 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
                             PA_IDXSET_FOREACH(source, u->core->sources, idx) {
                                 if ((pa_source*) ignore_device == source)
                                     continue;
+                                if (!PA_SOURCE_IS_LINKED(source->state))
+                                    continue;
                                 if (pa_streq(source->name, device_name)) {
                                     found = true;
                                     idx = source->index; /* Is this needed? */