[vlc-devel] [PATCH 1/2] win32: add cancel functions to be called in the APC

Steve Lhomme robux4 at videolabs.io
Fri Jan 15 17:16:21 CET 2016


--
this is going to be useful to cancel socket tasks that are not alertable
---
 include/vlc_threads.h | 17 +++++++++++++++++
 src/win32/thread.c    | 30 ++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index b31c885..164847e 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -858,11 +858,16 @@ VLC_API unsigned vlc_GetCPUCount(void);
  */
 # define vlc_cleanup_pop( ) pthread_cleanup_pop (0)
 
+# define vlc_cancel_push( routine, arg )
+# define vlc_cancel_pop( )
+
 #else
 enum
 {
     VLC_CLEANUP_PUSH,
     VLC_CLEANUP_POP,
+    VLC_CANCEL_PUSH,
+    VLC_CANCEL_POP,
 };
 typedef struct vlc_cleanup_t vlc_cleanup_t;
 
@@ -885,6 +890,18 @@ struct vlc_cleanup_t
         vlc_control_cancel (VLC_CLEANUP_POP); \
     } while (0)
 
+#define vlc_cancel_push( routine, arg ) \
+    do { \
+        vlc_cleanup_t vlc_cleaner_data = { NULL, routine, arg, }; \
+        vlc_control_cancel (VLC_CANCEL_PUSH, &vlc_cleaner_data)
+
+/* The cleanup routine is only executed if the canceler hasn't been
+ * called
+ */
+# define vlc_cancel_pop(  ) \
+        vlc_control_cancel (VLC_CANCEL_POP); \
+    } while (0)
+
 #endif /* !LIBVLC_USE_PTHREAD_CLEANUP */
 
 static inline void vlc_cleanup_lock (void *lock)
diff --git a/src/win32/thread.c b/src/win32/thread.c
index 774d4db..d9d2b50 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -442,6 +442,7 @@ retry:
 
 /*** Threads ***/
 static DWORD thread_key;
+static DWORD cancel_key;
 
 struct vlc_thread
 {
@@ -454,6 +455,7 @@ struct vlc_thread
     atomic_bool    killed;
 #endif
     vlc_cleanup_t *cleaners;
+    vlc_cleanup_t *cancelers;
 
     void        *(*entry) (void *);
     void          *data;
@@ -499,6 +501,7 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
     atomic_init(&th->killed, false);
 #endif
     th->cleaners = NULL;
+    th->cancelers = NULL;
 
     /* When using the MSVCRT C library you have to use the _beginthreadex
      * function instead of CreateThread, otherwise you'll end up with
@@ -573,7 +576,11 @@ static void CALLBACK vlc_cancel_self (ULONG_PTR self)
     struct vlc_thread *th = (void *)self;
 
     if (likely(th != NULL))
+    {
         th->killed = true;
+        for (vlc_cleanup_t *p = th->cancelers; p != NULL; p = p->next)
+            p->proc (p->data);
+    }
 }
 #endif
 
@@ -662,6 +669,22 @@ void vlc_control_cancel (int cmd, ...)
             th->cleaners = th->cleaners->next;
             break;
         }
+
+        case VLC_CANCEL_PUSH:
+        {
+            /* cleaner is a pointer to the caller stack, no need to allocate
+             * and copy anything. As a nice side effect, this cannot fail. */
+            vlc_cleanup_t *canceler = va_arg (ap, vlc_cleanup_t *);
+            canceler->next = th->cancelers;
+            th->cancelers = canceler;
+            break;
+        }
+
+        case VLC_CANCEL_POP:
+        {
+            th->cancelers = th->cancelers->next;
+            break;
+        }
     }
     va_end (ap);
 }
@@ -1031,6 +1054,12 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
             thread_key = TlsAlloc();
             if (unlikely(thread_key == TLS_OUT_OF_INDEXES))
                 return FALSE;
+            cancel_key = TlsAlloc();
+            if (unlikely(cancel_key == TLS_OUT_OF_INDEXES))
+            {
+                TlsFree(thread_key);
+                return FALSE;
+            }
             InitializeCriticalSection (&clock_lock);
             vlc_mutex_init (&super_mutex);
             vlc_cond_init (&super_variable);
@@ -1043,6 +1072,7 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
             vlc_cond_destroy (&super_variable);
             vlc_mutex_destroy (&super_mutex);
             DeleteCriticalSection (&clock_lock);
+            TlsFree(cancel_key);
             TlsFree(thread_key);
             break;
 
-- 
2.6.0.windows.1



More information about the vlc-devel mailing list