Commit 685788f5 authored by Pierre Ynard's avatar Pierre Ynard

WinCE: switch back vlc_thread_t to an allocated struct

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