summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-08-16 00:45:23 +0200
committerLennart Poettering <lennart@poettering.net>2009-08-16 00:45:23 +0200
commit4c29ba9c332dd682ced5ed668aede16aa5861128 (patch)
treec0e71f7bd470def7bbd9f97419dd5037f7f82cc4 /src
parent2a39663ab61614982c52e244bde596dcc1a08f37 (diff)
modules: add various checks to avoid selecting objects that are not linked or in another unclear state
Diffstat (limited to 'src')
-rw-r--r--src/modules/module-intended-roles.c54
-rw-r--r--src/modules/module-rescue-streams.c6
-rw-r--r--src/modules/module-stream-restore.c18
-rw-r--r--src/pulsecore/namereg.c30
4 files changed, 92 insertions, 16 deletions
diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c
index c697209a..b9924dfd 100644
--- a/src/modules/module-intended-roles.c
+++ b/src/modules/module-intended-roles.c
@@ -127,6 +127,9 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
if (s == def)
continue;
+ if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+ continue;
+
if (role_match(s->proplist, role)) {
new_data->sink = s;
new_data->save_sink = FALSE;
@@ -173,6 +176,9 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
if (s == def)
continue;
+ if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+ continue;
+
if (role_match(s->proplist, role)) {
new_data->source = s;
new_data->save_source = FALSE;
@@ -201,6 +207,17 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->save_sink)
continue;
+ /* Skip this if it is already in the process of being moved
+ * anyway */
+ if (!si->sink)
+ continue;
+
+ /* It might happen that a stream and a sink are set up at the
+ same time, in which case we want to make sure we don't
+ interfere with that */
+ if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si)))
+ continue;
+
if (!(role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE)))
continue;
@@ -237,6 +254,17 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->direct_on_input)
continue;
+ /* Skip this if it is already in the process of being moved
+ * anyway */
+ if (!so->source)
+ continue;
+
+ /* It might happen that a stream and a source are set up at the
+ same time, in which case we want to make sure we don't
+ interfere with that */
+ if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(so)))
+ continue;
+
if (!(role = pa_proplist_gets(so->proplist, PA_PROP_MEDIA_ROLE)))
continue;
@@ -275,24 +303,28 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
uint32_t jdx;
pa_sink *d;
+ if (!si->sink)
+ continue;
+
if (!(role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE)))
continue;
/* Would the default sink fit? If so, let's use it */
- if (def != sink && role_match(def->proplist, role)) {
- pa_sink_input_move_to(si, def, FALSE);
- continue;
- }
+ if (def != sink && role_match(def->proplist, role))
+ if (pa_sink_input_move_to(si, def, FALSE) >= 0)
+ continue;
/* Try to find some other fitting sink */
PA_IDXSET_FOREACH(d, c->sinks, jdx) {
if (d == def || d == sink)
continue;
- if (role_match(d->proplist, role)) {
- pa_sink_input_move_to(si, d, FALSE);
- break;
- }
+ if (!PA_SINK_IS_LINKED(pa_sink_get_state(d)))
+ continue;
+
+ if (role_match(d->proplist, role))
+ if (pa_sink_input_move_to(si, d, FALSE) >= 0)
+ break;
}
}
@@ -325,6 +357,9 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
if (so->direct_on_input)
continue;
+ if (!so->source)
+ continue;
+
if (!(role = pa_proplist_gets(so->proplist, PA_PROP_MEDIA_ROLE)))
continue;
@@ -339,6 +374,9 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
if (d == def || d == source)
continue;
+ if (!PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
+ continue;
+
if (role_match(d->proplist, role) && !source->monitor_of == !d->monitor_of) {
pa_source_output_move_to(so, d, FALSE);
break;
diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
index 82f693f9..722d84b2 100644
--- a/src/modules/module-rescue-streams.c
+++ b/src/modules/module-rescue-streams.c
@@ -71,6 +71,9 @@ static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip
if (target == skip)
continue;
+ if (!PA_SINK_IS_LINKED(pa_sink_get_state(target)))
+ continue;
+
if (pa_sink_input_may_move_to(i, target))
return target;
}
@@ -159,6 +162,9 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou
if (!target->monitor_of != !skip->monitor_of)
continue;
+ if (!PA_SOURCE_IS_LINKED(pa_source_get_state(target)))
+ continue;
+
if (pa_source_output_may_move_to(o, target))
return target;
}
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 727a5275..e560bd28 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -540,6 +540,11 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->save_sink)
continue;
+ /* Skip this if it is already in the process of being moved
+ * anyway */
+ if (!si->sink)
+ continue;
+
/* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't
interfere with that */
@@ -584,6 +589,10 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->direct_on_input)
continue;
+ /* Skip this if it is already in the process of being moved anyway */
+ if (!so->source)
+ continue;
+
/* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't
interfere with that */
@@ -623,6 +632,9 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
char *name;
struct entry *e;
+ if (!si->sink)
+ continue;
+
if (!(name = get_name(si->proplist, "sink-input")))
continue;
@@ -663,6 +675,12 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
char *name;
struct entry *e;
+ if (so->direct_on_input)
+ continue;
+
+ if (!so->source)
+ continue;
+
if (!(name = get_name(so->proplist, "source-output")))
continue;
diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
index 9df2f583..e26923d4 100644
--- a/src/pulsecore/namereg.c
+++ b/src/pulsecore/namereg.c
@@ -223,6 +223,9 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {
pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
pa_assert(c);
+ if (s && !PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+ return NULL;
+
if (c->default_sink != s) {
c->default_sink = s;
pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
@@ -234,6 +237,9 @@ pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
pa_assert(c);
+ if (s && !PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+ return NULL;
+
if (c->default_source != s) {
c->default_source = s;
pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
@@ -244,14 +250,19 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
pa_sink *pa_namereg_get_default_sink(pa_core *c) {
pa_sink *s;
+ uint32_t idx;
pa_assert(c);
- if (c->default_sink)
+ if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
return c->default_sink;
- if ((s = pa_idxset_first(c->sinks, NULL)))
- return pa_namereg_set_default_sink(c, s);
+ /* FIXME: the selection here should be based priority values on
+ * the sinks */
+
+ PA_IDXSET_FOREACH(s, c->sinks, idx)
+ if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+ return pa_namereg_set_default_sink(c, s);
return NULL;
}
@@ -262,15 +273,18 @@ pa_source *pa_namereg_get_default_source(pa_core *c) {
pa_assert(c);
- if (c->default_source)
+ if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)))
return c->default_source;
- for (s = PA_SOURCE(pa_idxset_first(c->sources, &idx)); s; s = PA_SOURCE(pa_idxset_next(c->sources, &idx)))
- if (!s->monitor_of)
+ /* First, try to find one that isn't a monitor */
+ PA_IDXSET_FOREACH(s, c->sources, idx)
+ if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
return pa_namereg_set_default_source(c, s);
- if ((s = pa_idxset_first(c->sources, NULL)))
- return pa_namereg_set_default_source(c, s);
+ /* Then, fallback to a monitor */
+ PA_IDXSET_FOREACH(s, c->sources, idx)
+ if (PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+ return pa_namereg_set_default_source(c, s);
return NULL;
}