[vlc-devel] [PATCH] win32/thread: avoid waking up every 50ms to see if the thread is canceled

Steve Lhomme robux4 at gmail.com
Mon Jul 20 15:23:26 CEST 2015


From: Steve Lhomme <robUx4 at gmail.com>

set the killEvent when we cancel the thread, which will wake up vlc_WaitForMultipleObjects()
---
 src/win32/thread.c | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/win32/thread.c b/src/win32/thread.c
index 39711b4..ed9fc72 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -49,10 +49,10 @@ static vlc_cond_t  super_variable;
 static bool isCancelled(void);
 #endif
 
-static DWORD vlc_WaitForMultipleObjects (DWORD count, const HANDLE *handles,
+static DWORD vlc_WaitForMultipleObjects (DWORD count, HANDLE handle,
                                          DWORD delay)
 {
-    DWORD ret;
+    DWORD ret = WAIT_FAILED;
     if (count == 0)
     {
 #if VLC_WINSTORE_APP
@@ -73,20 +73,16 @@ static DWORD vlc_WaitForMultipleObjects (DWORD count, const HANDLE *handles,
         if (ret == 0)
             ret = WAIT_TIMEOUT;
     }
-    else {
+    else if (count == 1 && handle != NULL)
+    {
 #if VLC_WINSTORE_APP
-        do {
-            DWORD new_delay = 50;
-            if (new_delay > delay)
-                new_delay = delay;
-            ret = WaitForMultipleObjectsEx (count, handles, FALSE, new_delay, TRUE);
-            if (delay != INFINITE)
-                delay -= new_delay;
-            if (isCancelled())
-                ret = WAIT_IO_COMPLETION;
-        } while (delay && ret == WAIT_TIMEOUT);
+        struct vlc_thread *th = TlsGetValue(thread_key);
+        HANDLE handles[2] = { handle, NULL };
+        if (th != NULL)
+            handles[count++] = th->killEvent;
+        ret = WaitForMultipleObjectsEx(count, handles, FALSE, delay, TRUE);
 #else
-        ret = WaitForMultipleObjectsEx (count, handles, FALSE, delay, TRUE);
+        ret = WaitForSingleObjectsEx (count, handle, FALSE, delay, TRUE);
 #endif
     }
 
@@ -100,7 +96,7 @@ static DWORD vlc_WaitForMultipleObjects (DWORD count, const HANDLE *handles,
 
 static DWORD vlc_WaitForSingleObject (HANDLE handle, DWORD delay)
 {
-    return vlc_WaitForMultipleObjects (1, &handle, delay);
+    return vlc_WaitForMultipleObjects (1, handle, delay);
 }
 
 static DWORD vlc_Sleep (DWORD delay)
@@ -452,6 +448,7 @@ struct vlc_thread
     bool           killed;
 #else
     atomic_bool    killed;
+    HANDLE         killEvent;
 #endif
     vlc_cleanup_t *cleaners;
 
@@ -519,6 +516,16 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
     }
     else
         th->id = (HANDLE)h;
+#if VLC_WINSTORE_APP
+    th->killEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (th->killEvent == NULL)
+    {
+        if (th->id != NULL)
+            CloseHandle(th->id);
+        free (th);
+        return VLC_EGENERIC;
+    }
+#endif
 
     if (p_handle != NULL)
         *p_handle = th;
@@ -543,6 +550,9 @@ void vlc_join (vlc_thread_t th, void **result)
 
     if (result != NULL)
         *result = th->data;
+#if VLC_WINSTORE_APP
+    CloseHandle(th->killEvent);
+#endif
     CloseHandle (th->id);
     free (th);
 }
@@ -583,6 +593,7 @@ void vlc_cancel (vlc_thread_t th)
     QueueUserAPC (vlc_cancel_self, th->id, (uintptr_t)th);
 #else
     atomic_store (&th->killed, true);
+    SetEvent(th->killEvent);
 #endif
 }
 
-- 
2.4.2




More information about the vlc-devel mailing list