[vlc-commits] win32: avoid broadcast in vlc_cond_signal()

Rémi Denis-Courmont git at videolan.org
Sun May 17 16:09:27 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun May 17 16:03:18 2015 +0300| [8762b9415cbb0ab65b409ee2999e69a94901ab30] | committer: Rémi Denis-Courmont

win32: avoid broadcast in vlc_cond_signal()

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8762b9415cbb0ab65b409ee2999e69a94901ab30
---

 src/win32/thread.c |   32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/src/win32/thread.c b/src/win32/thread.c
index 46fa357..c30e67d 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -225,10 +225,29 @@ void vlc_cond_destroy(vlc_cond_t *wait)
     CloseHandle(wait->semaphore);
 }
 
-void vlc_cond_signal (vlc_cond_t *p_condvar)
+static LONG InterlockedDecrementNonZero(LONG volatile *dst)
 {
-    /* This is suboptimal but works. */
-    vlc_cond_broadcast (p_condvar);
+    LONG cmp, val = 1;
+
+    do
+    {
+        cmp = val;
+        val = InterlockedCompareExchange(dst, val - 1, val);
+        if (val == 0)
+            return 0;
+    }
+    while (cmp != val);
+
+    return val;
+}
+
+void vlc_cond_signal(vlc_cond_t *wait)
+{
+    if (!wait->clock)
+        return;
+
+    if (InterlockedDecrementNonZero(&wait->waiters) > 0)
+        ReleaseSemaphore(wait->semaphore, 1, NULL);
 }
 
 void vlc_cond_broadcast(vlc_cond_t *wait)
@@ -243,6 +262,8 @@ void vlc_cond_broadcast(vlc_cond_t *wait)
 
 void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock)
 {
+    DWORD result;
+
     vlc_testcancel();
 
     if (!wait->clock)
@@ -253,8 +274,11 @@ void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock)
 
     InterlockedIncrement(&wait->waiters);
     vlc_mutex_unlock(lock);
-    vlc_WaitForSingleObject(wait->semaphore, INFINITE);
+    result = vlc_WaitForSingleObject(wait->semaphore, INFINITE);
     vlc_mutex_lock(lock);
+
+    if (result == WAIT_IO_COMPLETION)
+        vlc_testcancel();
 }
 
 int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline)



More information about the vlc-commits mailing list