[PATCH] winepulse: Wake all threads when operations are completed

Andrew Eikum aeikum at codeweavers.com
Tue Mar 13 12:57:04 CDT 2018


If threads A and B queue operations simultaneously, it would
previously be possible for B's operation to complete and wake thread A
from cond_wait, which would fail its condition check and then deadlock
as only thread B is awoken when A's operation completes.

This change wakes all threads waiting on the cond var, and each thread
already checks its condition before choosing to continue.

Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/winepulse.drv/mmdevdrv.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
index 50b4188e5e..32f7acb91d 100644
--- a/dlls/winepulse.drv/mmdevdrv.c
+++ b/dlls/winepulse.drv/mmdevdrv.c
@@ -260,7 +260,7 @@ static inline ACImpl *impl_from_IAudioStreamVolume(IAudioStreamVolume *iface)
  * but that cannot be used because it uses pthread_create directly
  *
  * pa_threaded_mainloop_(un)lock -> pthread_mutex_(un)lock
- * pa_threaded_mainloop_signal -> pthread_cond_signal
+ * pa_threaded_mainloop_signal -> pthread_cond_broadcast
  * pa_threaded_mainloop_wait -> pthread_cond_wait
  */
 
@@ -277,7 +277,7 @@ static DWORD CALLBACK pulse_mainloop_thread(void *tmp) {
     pulse_ml = pa_mainloop_new();
     pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
     pthread_mutex_lock(&pulse_lock);
-    pthread_cond_signal(&pulse_cond);
+    pthread_cond_broadcast(&pulse_cond);
     pa_mainloop_run(pulse_ml, &ret);
     pthread_mutex_unlock(&pulse_lock);
     pa_mainloop_free(pulse_ml);
@@ -307,14 +307,14 @@ static void pulse_contextcallback(pa_context *c, void *userdata)
             WARN("Context failed: %s\n", pa_strerror(pa_context_errno(c)));
             break;
     }
-    pthread_cond_signal(&pulse_cond);
+    pthread_cond_broadcast(&pulse_cond);
 }
 
 static void pulse_stream_state(pa_stream *s, void *user)
 {
     pa_stream_state_t state = pa_stream_get_state(s);
     TRACE("Stream state changed to %i\n", state);
-    pthread_cond_signal(&pulse_cond);
+    pthread_cond_broadcast(&pulse_cond);
 }
 
 static const enum pa_channel_position pulse_pos_from_wfx[] = {
@@ -632,7 +632,7 @@ static void dump_attr(const pa_buffer_attr *attr) {
 static void pulse_op_cb(pa_stream *s, int success, void *user) {
     TRACE("Success: %i\n", success);
     *(int*)user = success;
-    pthread_cond_signal(&pulse_cond);
+    pthread_cond_broadcast(&pulse_cond);
 }
 
 static void pulse_attr_update(pa_stream *s, void *user) {
-- 
2.16.2




More information about the wine-devel mailing list