WinCE: switch back vlc_thread_t to an allocated struct
authorPierre Ynard <linkfanel@yahoo.fr>
Thu, 13 Aug 2009 11:21:09 +0000 (13:21 +0200)
committerPierre Ynard <linkfanel@yahoo.fr>
Thu, 13 Aug 2009 11:21:09 +0000 (13:21 +0200)
WinCE needs the cancellation event handle along with the thread handle,
so we have to switch back to a struct on WinCE. Which causes great
ugliness. Fix the build with the recent changes, and simplify some
related Win32 code.

include/vlc_threads.h
src/misc/threads.c
src/misc/w32thread.c

index 77a7608..7d65e4f 100644 (file)
@@ -112,7 +112,15 @@ typedef pthread_key_t   vlc_threadvar_t;
 typedef struct vlc_timer *vlc_timer_t;
 
 #elif defined( WIN32 )
+#if !defined( UNDER_CE )
 typedef HANDLE vlc_thread_t;
+#else
+typedef struct
+{
+    HANDLE handle;
+    HANDLE cancel_event;
+} *vlc_thread_t;
+#endif
 
 typedef struct
 {
index 0341747..7b68ce7 100644 (file)
@@ -148,7 +148,11 @@ int __vlc_thread_set_priority( vlc_object_t *p_this, const char * psz_file,
 #elif defined( WIN32 ) || defined( UNDER_CE )
     VLC_UNUSED( psz_file); VLC_UNUSED( i_line );
 
+#ifndef UNDER_CE
     if( !SetThreadPriority(p_priv->thread_id, i_priority) )
+#else
+    if( !SetThreadPriority(p_priv->thread_id->handle, i_priority) )
+#endif
     {
         msg_Warn( p_this, "couldn't set a faster priority" );
         return 1;
index 7e2611f..9b018ce 100644 (file)
@@ -411,6 +411,9 @@ struct vlc_entry_data
 {
     void * (*func) (void *);
     void *  data;
+#ifdef UNDER_CE
+    HANDLE  cancel_event;
+#endif
 };
 
 static unsigned __stdcall vlc_entry (void *p)
@@ -422,7 +425,7 @@ static unsigned __stdcall vlc_entry (void *p)
     free (p);
 
 #ifdef UNDER_CE
-    cancel_data.cancel_event = data.handle->cancel_event;
+    cancel_data.cancel_event = data.cancel_event;
 #endif
 
     vlc_threadvar_set (cancel_key, &cancel_data);
@@ -433,10 +436,7 @@ static unsigned __stdcall vlc_entry (void *p)
 int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
                int priority)
 {
-    /* When using the MSVCRT C library you have to use the _beginthreadex
-     * function instead of CreateThread, otherwise you'll end up with
-     * memory leaks and the signal functions not working (see Microsoft
-     * Knowledge Base, article 104641) */
+    int err = ENOMEM;
     HANDLE hThread;
 
     struct vlc_entry_data *entry_data = malloc (sizeof (*entry_data));
@@ -445,51 +445,73 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
     entry_data->func = entry;
     entry_data->data = data;
 
-#if defined( UNDER_CE )
-    th->cancel_event = CreateEvent (NULL, FALSE, FALSE, NULL);
-    if (th->cancel_event == NULL)
-    {
-        free (entry_data);
-        return errno;
-    }
-    hThread = CreateThread (NULL, 128*1024, vlc_entry, entry_data, CREATE_SUSPENDED, NULL);
-#else
+#ifndef UNDER_CE
+    /* When using the MSVCRT C library you have to use the _beginthreadex
+     * function instead of CreateThread, otherwise you'll end up with
+     * memory leaks and the signal functions not working (see Microsoft
+     * Knowledge Base, article 104641) */
     hThread = (HANDLE)(uintptr_t)
         _beginthreadex (NULL, 0, vlc_entry, entry_data, CREATE_SUSPENDED, NULL);
-#endif
+    if (! hThread)
+    {
+        err = errno;
+        goto error;
+    }
 
-    if (hThread)
+    /* 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))
     {
-#ifndef UNDER_CE
-        /* 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);
-            free (entry_data);
-            return ENOMEM;
-        }
+        CloseHandle (hThread);
+        goto error;
+    }
+
 #else
-        th->handle = hThread;
-#endif
+    vlc_thread_t th = malloc (sizeof (*th));
+    if (th == NULL)
+        goto error;
+    th->cancel_event = CreateEvent (NULL, FALSE, FALSE, NULL);
+    if (th->cancel_event == NULL)
+    {
+        free (th);
+        goto error;
+    }
+    entry_data->cancel_event = th->cancel_event;
 
-        ResumeThread (hThread);
-        if (priority)
-            SetThreadPriority (hThread, priority);
-        return 0;
+    /* Not sure if CREATE_SUSPENDED + ResumeThread() is any useful on WinCE.
+     * Thread handles act up, too. */
+    th->handle = CreateThread (NULL, 128*1024, vlc_entry, entry_data,
+                               CREATE_SUSPENDED, NULL);
+    if (th->handle == NULL)
+    {
+        CloseHandle (th->cancel_event);
+        free (th);
+        goto error;
     }
 
-#ifdef UNDER_CE
-    CloseHandle (th->cancel_event);
+    *p_handle = th;
+    hThread = th->handle;
+
 #endif
+
+    ResumeThread (hThread);
+    if (priority)
+        SetThreadPriority (hThread, priority);
+
+    return 0;
+
+error:
     free (entry_data);
-    return errno;
+    return err;
 }
 
 void vlc_join (vlc_thread_t handle, void **result)
 {
+#ifdef UNDER_CE
+# define handle handle->handle
+#endif
     do
         vlc_testcancel ();
     while (WaitForSingleObjectEx (handle, INFINITE, TRUE)
@@ -498,13 +520,21 @@ void vlc_join (vlc_thread_t handle, void **result)
     CloseHandle (handle);
     assert (result == NULL); /* <- FIXME if ever needed */
 #ifdef UNDER_CE
+# undef handle
     CloseHandle (handle->cancel_event);
+    free (handle);
 #endif
 }
 
 void vlc_detach (vlc_thread_t handle)
 {
+#ifndef UNDER_CE
     CloseHandle (handle);
+#else
+    /* FIXME: handle->cancel_event leak */
+    CloseHandle (handle->handle);
+    free (handle);
+#endif
 }
 
 /*** Thread cancellation ***/