Commit 1fb975e7 authored by David Reid's avatar David Reid

Another potential fix for a data race error with PulseAudio.

Public issue https://github.com/mackron/miniaudio/issues/235
parent 54f1f480
...@@ -22810,9 +22810,11 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22810,9 +22810,11 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
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); /* With the mainloop created we can now start it. */
if (pContext->pulse.pPulseContext == NULL) { 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_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio context.", MA_FAILED_TO_INIT_BACKEND); if (result != MA_SUCCESS) {
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_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));
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->pulse.pulseSO); ma_dlclose(pContext, pContext->pulse.pulseSO);
...@@ -22820,10 +22822,12 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22820,10 +22822,12 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
/* 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)); 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);
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); if (pContext->pulse.pPulseContext == NULL) {
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_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));
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->pulse.pulseSO); ma_dlclose(pContext, pContext->pulse.pulseSO);
...@@ -22831,11 +22835,13 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22831,11 +22835,13 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
/* We now need to start the mainloop. Once the loop has started we can then wait for the PulseAudio context to connect. */ /* Now we need to connect to the context. Everything is asynchronous so we need to wait for it to connect before returning. */
result = ma_result_from_pulse(((ma_pa_threaded_mainloop_start_proc)pContext->pulse.pa_threaded_mainloop_start)((ma_pa_threaded_mainloop*)pContext->pulse.pMainLoop)); 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));
ma_mainloop_unlock__pulse(pContext, "ma_context_init__pulse");
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
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 connect PulseAudio context.", result);
((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)pContext->pulse.pPulseContext); ((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));
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->pulse.pulseSO); ma_dlclose(pContext, pContext->pulse.pulseSO);
...@@ -22843,6 +22849,7 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -22843,6 +22849,7 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
return result; return result;
} }
/* 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) {
((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));
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