Commit 120ad814 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Win32: fix race between vlc_cancel() and vlc_threadvar_set()

parent e7b765a1
...@@ -505,6 +505,7 @@ struct vlc_entry_data ...@@ -505,6 +505,7 @@ struct vlc_entry_data
{ {
void * (*func) (void *); void * (*func) (void *);
void * data; void * data;
vlc_sem_t ready;
#ifdef UNDER_CE #ifdef UNDER_CE
HANDLE cancel_event; HANDLE cancel_event;
#endif #endif
...@@ -512,18 +513,17 @@ struct vlc_entry_data ...@@ -512,18 +513,17 @@ struct vlc_entry_data
static unsigned __stdcall vlc_entry (void *p) static unsigned __stdcall vlc_entry (void *p)
{ {
struct vlc_entry_data *entry = p;
vlc_cancel_t cancel_data = VLC_CANCEL_INIT; vlc_cancel_t cancel_data = VLC_CANCEL_INIT;
struct vlc_entry_data data; void *(*func) (void *) = entry->func;
void *data = entry->data;
memcpy (&data, p, sizeof (data));
free (p);
#ifdef UNDER_CE #ifdef UNDER_CE
cancel_data.cancel_event = data.cancel_event; cancel_data.cancel_event = entry->cancel_event;
#endif #endif
vlc_threadvar_set (cancel_key, &cancel_data); vlc_threadvar_set (cancel_key, &cancel_data);
data.func (data.data); vlc_sem_post (&entry->ready);
func (data);
return 0; return 0;
} }
...@@ -538,6 +538,7 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data, ...@@ -538,6 +538,7 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
return ENOMEM; return ENOMEM;
entry_data->func = entry; entry_data->func = entry;
entry_data->data = data; entry_data->data = data;
vlc_sem_init (&entry_data->ready, 0);
#ifndef UNDER_CE #ifndef UNDER_CE
/* When using the MSVCRT C library you have to use the _beginthreadex /* When using the MSVCRT C library you have to use the _beginthreadex
...@@ -594,9 +595,17 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data, ...@@ -594,9 +595,17 @@ int vlc_clone (vlc_thread_t *p_handle, void * (*entry) (void *), void *data,
if (priority) if (priority)
SetThreadPriority (hThread, 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; return 0;
error: error:
vlc_sem_destroy (&entry_data->ready);
free (entry_data); free (entry_data);
return err; return err;
} }
......
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