From: Paul Gofman pgofman@codeweavers.com
--- dlls/winepulse.drv/pulse.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index e83ef64e887..4b287578e8b 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -209,10 +209,10 @@ static BOOL wait_pa_operation_complete(pa_operation *o) if (!o) return FALSE;
- while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) + while (pulse_ml && pa_operation_get_state(o) == PA_OPERATION_RUNNING) pulse_cond_wait(); pa_operation_unref(o); - return TRUE; + return !!pulse_ml; }
/* Following pulseaudio design here, mainloop has the lock taken whenever @@ -244,6 +244,7 @@ static NTSTATUS pulse_process_attach(void *args)
pthread_mutexattr_init(&attr); pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); + pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
if (pthread_mutex_init(&pulse_mutex, &attr) != 0) pthread_mutex_init(&pulse_mutex, NULL); @@ -275,6 +276,14 @@ static NTSTATUS pulse_process_detach(void *args) return STATUS_SUCCESS; }
+static void pulse_main_loop_thread_cleanup(void *context) +{ + TRACE("Main loop thread is being aborted.\n"); + + pulse_ml = NULL; + pulse_broadcast(); +} + static NTSTATUS pulse_main_loop(void *args) { struct main_loop_params *params = args; @@ -283,7 +292,9 @@ static NTSTATUS pulse_main_loop(void *args) pulse_ml = pa_mainloop_new(); pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL); NtSetEvent(params->event, NULL); + pthread_cleanup_push(pulse_main_loop_thread_cleanup, NULL); pa_mainloop_run(pulse_ml, &ret); + pthread_cleanup_pop(0); pa_mainloop_free(pulse_ml); pulse_unlock(); return STATUS_SUCCESS; @@ -1247,7 +1258,7 @@ static NTSTATUS pulse_release_stream(void *args) pulse_lock(); if (PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream))) { pa_stream_disconnect(stream->stream); - while (PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream))) + while (pulse_ml && PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream))) pulse_cond_wait(); } pa_stream_unref(stream->stream);