Commit 8004aa1a authored by Eduardo Bart's avatar Eduardo Bart

Fix data race on pulseaudio startup

parent ba7be0d4
...@@ -22813,9 +22813,13 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22813,9 +22813,13 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
/* We should start the mainloop locked and unlock once ready to wait . */
ma_mainloop_lock__pulse(pContext, "ma_context_init__pulse");
/* With the mainloop created we can now start it. */ /* With the mainloop created we can now start it. */
result = ma_result_from_pulse(((ma_pa_threaded_mainloop_start_proc)pContext->pulse.pa_threaded_mainloop_start)((ma_pa_threaded_mainloop*)pContext->pulse.pMainLoop)); result = ma_result_from_pulse(((ma_pa_threaded_mainloop_start_proc)pContext->pulse.pa_threaded_mainloop_start)((ma_pa_threaded_mainloop*)pContext->pulse.pMainLoop));
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to start mainloop.", result); ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to start mainloop.", result);
((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)pContext->pulse.pPulseContext); ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)pContext->pulse.pPulseContext);
((ma_pa_threaded_mainloop_free_proc)pContext->pulse.pa_threaded_mainloop_free)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop)); ((ma_pa_threaded_mainloop_free_proc)pContext->pulse.pa_threaded_mainloop_free)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop));
...@@ -22825,10 +22829,9 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22825,10 +22829,9 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
ma_mainloop_lock__pulse(pContext, "ma_context_init__pulse");
pContext->pulse.pPulseContext = ((ma_pa_context_new_proc)pContext->pulse.pa_context_new)(((ma_pa_threaded_mainloop_get_api_proc)pContext->pulse.pa_threaded_mainloop_get_api)((ma_pa_threaded_mainloop*)pContext->pulse.pMainLoop), pConfig->pulse.pApplicationName); pContext->pulse.pPulseContext = ((ma_pa_context_new_proc)pContext->pulse.pa_context_new)(((ma_pa_threaded_mainloop_get_api_proc)pContext->pulse.pa_threaded_mainloop_get_api)((ma_pa_threaded_mainloop*)pContext->pulse.pMainLoop), pConfig->pulse.pApplicationName);
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
if (pContext->pulse.pPulseContext == NULL) { if (pContext->pulse.pPulseContext == NULL) {
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
result = ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio context.", MA_FAILED_TO_INIT_BACKEND); result = ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio context.", MA_FAILED_TO_INIT_BACKEND);
((ma_pa_threaded_mainloop_stop_proc)pContext->pulse.pa_threaded_mainloop_stop)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop)); ((ma_pa_threaded_mainloop_stop_proc)pContext->pulse.pa_threaded_mainloop_stop)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop));
((ma_pa_threaded_mainloop_free_proc)pContext->pulse.pa_threaded_mainloop_free)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop)); ((ma_pa_threaded_mainloop_free_proc)pContext->pulse.pa_threaded_mainloop_free)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop));
...@@ -22839,10 +22842,9 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22839,10 +22842,9 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
} }
/* Now we need to connect to the context. Everything is asynchronous so we need to wait for it to connect before returning. */ /* Now we need to connect to the context. Everything is asynchronous so we need to wait for it to connect before returning. */
ma_mainloop_lock__pulse(pContext, "ma_context_init__pulse");
result = ma_result_from_pulse(((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)((ma_pa_context*)pContext->pulse.pPulseContext, pConfig->pulse.pServerName, (pConfig->pulse.tryAutoSpawn) ? 0 : MA_PA_CONTEXT_NOAUTOSPAWN, NULL)); result = ma_result_from_pulse(((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)((ma_pa_context*)pContext->pulse.pPulseContext, pConfig->pulse.pServerName, (pConfig->pulse.tryAutoSpawn) ? 0 : MA_PA_CONTEXT_NOAUTOSPAWN, NULL));
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio context.", result); ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio context.", result);
((ma_pa_threaded_mainloop_stop_proc)pContext->pulse.pa_threaded_mainloop_stop)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop)); ((ma_pa_threaded_mainloop_stop_proc)pContext->pulse.pa_threaded_mainloop_stop)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop));
((ma_pa_threaded_mainloop_free_proc)pContext->pulse.pa_threaded_mainloop_free)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop)); ((ma_pa_threaded_mainloop_free_proc)pContext->pulse.pa_threaded_mainloop_free)((ma_pa_threaded_mainloop*)(pContext->pulse.pMainLoop));
...@@ -22852,6 +22854,9 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22852,6 +22854,9 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
/* Can now unlock. */
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
/* Since ma_context_init() runs synchronously we need to wait for the PulseAudio context to connect before we return. */ /* Since ma_context_init() runs synchronously we need to wait for the PulseAudio context to connect before we return. */
result = ma_context_wait_for_pa_context_to_connect__pulse(pContext); result = ma_context_wait_for_pa_context_to_connect__pulse(pContext);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment