pulseaudio: Be more aggressive with hotplug thread synchronization.
(Borrowed from the SDL2 branch.)
This commit is contained in:
parent
5cbdf1168e
commit
82ce05ad01
@ -847,28 +847,47 @@ static int SDLCALL HotplugThread(void *data)
|
||||
{
|
||||
uint32_t prev_default_sink_index = default_sink_index;
|
||||
uint32_t prev_default_source_index = default_source_index;
|
||||
pa_operation *op;
|
||||
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, HotplugCallback, NULL);
|
||||
PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_subscribe(pulseaudio_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SERVER, NULL, NULL));
|
||||
|
||||
/* don't WaitForPulseOperation on the subscription; when it's done we'll be able to get hotplug events, but waiting doesn't changing anything. */
|
||||
op = PULSEAUDIO_pa_context_subscribe(pulseaudio_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SERVER, NULL, NULL);
|
||||
|
||||
SDL_PostSemaphore((SDL_Semaphore *) data);
|
||||
|
||||
while (SDL_AtomicGet(&pulseaudio_hotplug_thread_active)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if (op && PULSEAUDIO_pa_operation_get_state(op) != PA_OPERATION_RUNNING) {
|
||||
PULSEAUDIO_pa_operation_unref(op);
|
||||
op = NULL;
|
||||
}
|
||||
|
||||
// Update default devices; don't hold the pulse lock during this, since it could deadlock vs a playing device that we're about to lock here.
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
CheckDefaultDevice(&prev_default_sink_index, default_sink_index);
|
||||
CheckDefaultDevice(&prev_default_source_index, default_source_index);
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, NULL, NULL); // Don't fire HotplugCallback again.
|
||||
if (op) {
|
||||
PULSEAUDIO_pa_operation_unref(op);
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, NULL, NULL);
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void PULSEAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture)
|
||||
{
|
||||
SDL_Semaphore *ready_sem = SDL_CreateSemaphore(0);
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL));
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_sink_info_list(pulseaudio_context, SinkInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
@ -888,7 +907,9 @@ static void PULSEAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_Audio
|
||||
|
||||
/* ok, we have a sane list, let's set up hotplug notifications now... */
|
||||
SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 1);
|
||||
pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL); /* !!! FIXME: this can probably survive in significantly less stack space. */
|
||||
pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, ready_sem); // !!! FIXME: this can probably survive in significantly less stack space.
|
||||
SDL_WaitSemaphore(ready_sem);
|
||||
SDL_DestroySemaphore(ready_sem);
|
||||
}
|
||||
|
||||
static void PULSEAUDIO_Deinitialize(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user