From a69c61fbfd17de6d8c475a50775d0b8ac73e278a Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 14 Aug 2020 12:08:58 +1000 Subject: [PATCH] Only assign context and mainloop once we have connected successfully If we fail to connect to the the pa server, we have an assigned context and mainloop that isn't connected. So, when PULSEAUDIO_pa_context_disconnect is called, pa asserts and crashes the application. Assertion 'pa_atomic_load(&(c)->_ref) >= 1' failed at pulse/context.c:1055, function pa_context_disconnect(). Aborting. --- src/audio/pulseaudio/SDL_pulseaudio.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index 829acc313..7a3af7bcd 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -295,32 +295,39 @@ ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context) return SDL_SetError("pa_mainloop_new() failed"); } - *_mainloop = mainloop; - mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop); SDL_assert(mainloop_api); /* this never fails, right? */ context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName()); if (!context) { + PULSEAUDIO_pa_mainloop_free(mainloop); return SDL_SetError("pa_context_new() failed"); } - *_context = context; /* Connect to the PulseAudio server */ if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) { + PULSEAUDIO_pa_context_unref(context); + PULSEAUDIO_pa_mainloop_free(mainloop); return SDL_SetError("Could not setup connection to PulseAudio"); } do { if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) { + PULSEAUDIO_pa_context_unref(context); + PULSEAUDIO_pa_mainloop_free(mainloop); return SDL_SetError("pa_mainloop_iterate() failed"); } state = PULSEAUDIO_pa_context_get_state(context); if (!PA_CONTEXT_IS_GOOD(state)) { + PULSEAUDIO_pa_context_unref(context); + PULSEAUDIO_pa_mainloop_free(mainloop); return SDL_SetError("Could not connect to PulseAudio"); } } while (state != PA_CONTEXT_READY); + *_context = context; + *_mainloop = mainloop; + return 0; /* connected and ready! */ }