Skip to content

Commit 007019a

Browse files
t-8chsfan5
authored andcommitted
ao_pipewire: for_each_sink: properly check termination condition
Doing a pw_thread_loop_wait() without checking conditions is invalid. The thread loop could be signalled for other reasons and in this case the wait needs to continue. PipeWire added such additional signaling in commit 33be898130f0 ("thread-loop: signal when started"). This meant that for_each_sink would return before the callbacks have fired and session_has_sink() would incorrectly return "false", failing the initialization of ao_pipewire. Fixes #11995
1 parent e8126e5 commit 007019a

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

audio/out/ao_pipewire.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,15 +354,21 @@ static void for_each_sink_registry_event_global(void *data, uint32_t id,
354354
}
355355

356356

357+
struct for_each_done_ctx {
358+
struct pw_thread_loop *loop;
359+
bool done;
360+
};
361+
357362
static const struct pw_registry_events for_each_sink_registry_events = {
358363
.version = PW_VERSION_REGISTRY_EVENTS,
359364
.global = for_each_sink_registry_event_global,
360365
};
361366

362367
static void for_each_sink_done(void *data, uint32_t it, int seq)
363368
{
364-
struct pw_thread_loop *loop = data;
365-
pw_thread_loop_signal(loop, false);
369+
struct for_each_done_ctx *ctx = data;
370+
ctx->done = true;
371+
pw_thread_loop_signal(ctx->loop, false);
366372
}
367373

368374
static const struct pw_core_events for_each_sink_core_events = {
@@ -376,12 +382,16 @@ static int for_each_sink(struct ao *ao, void (cb) (struct ao *ao, uint32_t id,
376382
struct priv *priv = ao->priv;
377383
struct pw_registry *registry;
378384
struct spa_hook core_listener;
385+
struct for_each_done_ctx done_ctx = {
386+
.loop = priv->loop,
387+
.done = false,
388+
};
379389
int ret = -1;
380390

381391
pw_thread_loop_lock(priv->loop);
382392

383393
spa_zero(core_listener);
384-
if (pw_core_add_listener(priv->core, &core_listener, &for_each_sink_core_events, priv->loop) < 0)
394+
if (pw_core_add_listener(priv->core, &core_listener, &for_each_sink_core_events, &done_ctx) < 0)
385395
goto unlock_loop;
386396

387397
registry = pw_core_get_registry(priv->core, PW_VERSION_REGISTRY, 0);
@@ -400,7 +410,8 @@ static int for_each_sink(struct ao *ao, void (cb) (struct ao *ao, uint32_t id,
400410
if (pw_registry_add_listener(registry, &registry_listener, &for_each_sink_registry_events, &revents_ctx) < 0)
401411
goto destroy_registry;
402412

403-
pw_thread_loop_wait(priv->loop);
413+
while (!done_ctx.done)
414+
pw_thread_loop_wait(priv->loop);
404415

405416
spa_hook_remove(&registry_listener);
406417

0 commit comments

Comments
 (0)