]> git.sesse.net Git - vlc/blobdiff - src/win32/thread.c
Rename the sdi module to decklink.
[vlc] / src / win32 / thread.c
index 7c0909d1b7e4a6db81df322dc1f1014aeabc9d6e..1d25b90320dcbb061e7f5e3d37aad0a93e8a2283 100644 (file)
@@ -505,6 +505,7 @@ struct vlc_entry_data
 {
     void * (*func) (void *);
     void *  data;
+    vlc_sem_t ready;
 #ifdef UNDER_CE
     HANDLE  cancel_event;
 #endif
@@ -512,18 +513,17 @@ struct vlc_entry_data
 
 static unsigned __stdcall vlc_entry (void *p)
 {
+    struct vlc_entry_data *entry = p;
     vlc_cancel_t cancel_data = VLC_CANCEL_INIT;
-    struct vlc_entry_data data;
-
-    memcpy (&data, p, sizeof (data));
-    free (p);
+    void *(*func) (void *) = entry->func;
+    void *data = entry->data;
 
 #ifdef UNDER_CE
-    cancel_data.cancel_event = data.cancel_event;
+    cancel_data.cancel_event = entry->cancel_event;
 #endif
-
     vlc_threadvar_set (cancel_key, &cancel_data);
-    data.func (data.data);
+    vlc_sem_post (&entry->ready);
+    func (data);
     return 0;
 }
 
@@ -538,6 +538,7 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
         return ENOMEM;
     entry_data->func = entry;
     entry_data->data = data;
+    vlc_sem_init (&entry_data->ready, 0);
 
 #ifndef UNDER_CE
     /* When using the MSVCRT C library you have to use the _beginthreadex
@@ -552,15 +553,7 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
         goto error;
     }
 
-    /* Thread closes the handle when exiting, duplicate it here
-     * to be on the safe side when joining. */
-    if (!DuplicateHandle (GetCurrentProcess (), hThread,
-                          GetCurrentProcess (), p_handle, 0, FALSE,
-                          DUPLICATE_SAME_ACCESS))
-    {
-        CloseHandle (hThread);
-        goto error;
-    }
+    *p_handle = hThread;
 
 #else
     vlc_thread_t th = malloc (sizeof (*th));
@@ -594,9 +587,17 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
     if (priority)
         SetThreadPriority (hThread, priority);
 
+    /* Prevent cancellation until cancel_data is initialized. */
+    /* XXX: This could be postponed to vlc_cancel() or avoided completely by
+     * passing the "right" pointer to vlc_cancel_self(). */
+    vlc_sem_wait (&entry_data->ready);
+    vlc_sem_destroy (&entry_data->ready);
+    free (entry_data);
+
     return 0;
 
 error:
+    vlc_sem_destroy (&entry_data->ready);
     free (entry_data);
     return err;
 }
@@ -636,8 +637,12 @@ void vlc_detach (vlc_thread_t handle)
 /* APC procedure for thread cancellation */
 static void CALLBACK vlc_cancel_self (ULONG_PTR dummy)
 {
+    vlc_cancel_t *nfo = vlc_threadvar_get (cancel_key);
+
+    if (likely(nfo != NULL))
+        nfo->killed = true;
+
     (void)dummy;
-    vlc_control_cancel (VLC_DO_CANCEL);
 }
 
 void vlc_cancel (vlc_thread_t thread_id)
@@ -685,7 +690,7 @@ void vlc_testcancel (void)
         for (vlc_cleanup_t *p = nfo->cleaners; p != NULL; p = p->next)
              p->proc (p->data);
 #ifndef UNDER_CE
-        _endthread ();
+        _endthreadex(0);
 #else
         ExitThread(0);
 #endif
@@ -705,10 +710,6 @@ void vlc_control_cancel (int cmd, ...)
     va_start (ap, cmd);
     switch (cmd)
     {
-        case VLC_DO_CANCEL:
-            nfo->killed = true;
-            break;
-
         case VLC_CLEANUP_PUSH:
         {
             /* cleaner is a pointer to the caller stack, no need to allocate