From dc34abc03ec8d3b7fb1668bcb59f604ae5ad2f40 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 2 Jun 2026 19:00:43 -0400 Subject: [PATCH] pipewire: Add SDL_HINT_AUDIO_DEVICE_STREAM_NAME callback earlier. Otherwise, it might cause a deadlock, if the output_callback runs in another thread while the guaranteed initial hint callback fires. One will wait for the SDL device lock, the other the pipewire thread loop lock, each already holding what the other needs. This way, the hint callback fires and we ignore it, since the stream isn't set up yet...which is good, because we're about to create the stream and set that exact same state on it directly anyhow. Now there's no chance of this deadlock happening. Reference Issue #15075. --- src/audio/pipewire/SDL_pipewire.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index 0719d04f0f..2161a5a386 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -1126,8 +1126,7 @@ static void SDLCALL PIPEWIRE_StreamNameChanged(void *userdata, const char *name, struct SDL_PrivateAudioData *priv = device->hidden; if (!priv || !priv->stream || !priv->loop) { - SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "PIPEWIRE: StreamNameChanged: stream not ready, skipping"); - return; + return; // stream not ready yet, skip it. } struct spa_dict_item items[] = { { PW_KEY_MEDIA_NAME, newValue } }; @@ -1270,6 +1269,9 @@ static bool PIPEWIRE_OpenDevice(SDL_AudioDevice *device) PIPEWIRE_pw_thread_loop_unlock(hotplug_loop); } + // add this early so it will do its initial trigger when we aren't setup--skipping the attempt to update the name--since we're already explicitly setting it here. + SDL_AddHintCallback(SDL_HINT_AUDIO_DEVICE_STREAM_NAME, PIPEWIRE_StreamNameChanged, device); + // Create the new stream priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props, recording ? &stream_input_events : &stream_output_events, device); @@ -1302,8 +1304,6 @@ static bool PIPEWIRE_OpenDevice(SDL_AudioDevice *device) return SDL_SetError("Pipewire: Stream error: %s", error); } - SDL_AddHintCallback(SDL_HINT_AUDIO_DEVICE_STREAM_NAME, PIPEWIRE_StreamNameChanged, device); - return true; }