void vlc_rwlock_rdlock (vlc_rwlock_t *lock)
{
vlc_mutex_lock (&lock->mutex);
- while (lock->writers > 0) /* Favor writers to avoid starving */
+ while (lock->writer != 0)
vlc_cond_wait (&lock->read_wait, &lock->mutex);
if (lock->readers == ULONG_MAX)
abort ();
/*** Threads ***/
-static unsigned __stdcall vlc_entry (void *data)
+void vlc_threads_setup (libvlc_int_t *p_libvlc)
+{
+ (void) p_libvlc;
+}
+
+struct vlc_entry_data
+{
+ void * (*func) (void *);
+ void * data;
+};
+
+static unsigned __stdcall vlc_entry (void *p)
{
vlc_cancel_t cancel_data = VLC_CANCEL_INIT;
- vlc_thread_t self = data;
+ struct vlc_entry_data data;
+
+ memcpy (&data, p, sizeof (data));
+ free (p);
+
#ifdef UNDER_CE
- cancel_data.cancel_event = self->cancel_event;
+ cancel_data.cancel_event = data.handle->cancel_event;
#endif
vlc_threadvar_set (cancel_key, &cancel_data);
- self->data = self->entry (self->data);
+ data.func (data.data);
return 0;
}
* memory leaks and the signal functions not working (see Microsoft
* Knowledge Base, article 104641) */
HANDLE hThread;
- vlc_thread_t th = malloc (sizeof (*th));
- if (th == NULL)
+ struct vlc_entry_data *entry_data = malloc (sizeof (*entry_data));
+ if (entry_data == NULL)
return ENOMEM;
+ entry_data->func = entry;
+ entry_data->data = data;
- th->data = data;
- th->entry = entry;
#if defined( UNDER_CE )
th->cancel_event = CreateEvent (NULL, FALSE, FALSE, NULL);
if (th->cancel_event == NULL)
{
- free(th);
+ free (entry_data);
return errno;
}
- hThread = CreateThread (NULL, 128*1024, vlc_entry, th, CREATE_SUSPENDED, NULL);
+ hThread = CreateThread (NULL, 128*1024, vlc_entry, entry_data, CREATE_SUSPENDED, NULL);
#else
hThread = (HANDLE)(uintptr_t)
- _beginthreadex (NULL, 0, vlc_entry, th, CREATE_SUSPENDED, NULL);
+ _beginthreadex (NULL, 0, vlc_entry, entry_data, CREATE_SUSPENDED, NULL);
#endif
if (hThread)
/* Thread closes the handle when exiting, duplicate it here
* to be on the safe side when joining. */
if (!DuplicateHandle (GetCurrentProcess (), hThread,
- GetCurrentProcess (), &th->handle, 0, FALSE,
+ GetCurrentProcess (), p_handle, 0, FALSE,
DUPLICATE_SAME_ACCESS))
{
CloseHandle (hThread);
- free (th);
+ free (entry_data);
return ENOMEM;
}
#else
ResumeThread (hThread);
if (priority)
SetThreadPriority (hThread, priority);
-
- *p_handle = th;
return 0;
}
- free (th);
return errno;
}
{
do
vlc_testcancel ();
- while (WaitForSingleObjectEx (handle->handle, INFINITE, TRUE)
+ while (WaitForSingleObjectEx (handle, INFINITE, TRUE)
== WAIT_IO_COMPLETION);
- CloseHandle (handle->handle);
- if (result)
- *result = handle->data;
+ CloseHandle (handle);
+ assert (result == NULL); /* <- FIXME if ever needed */
#ifdef UNDER_CE
CloseHandle (handle->cancel_event);
#endif
- free (handle);
}
+void vlc_detach (vlc_thread_t handle)
+{
+ CloseHandle (handle);
+}
/*** Thread cancellation ***/
void vlc_cancel (vlc_thread_t thread_id)
{
#ifndef UNDER_CE
- QueueUserAPC (vlc_cancel_self, thread_id->handle, 0);
+ QueueUserAPC (vlc_cancel_self, thread_id, 0);
#else
SetEvent (thread_id->cancel_event);
#endif
/*** Timers ***/
+struct vlc_timer
+{
+ HANDLE handle;
+ void (*func) (void *);
+ void *data;
+};
+
static void CALLBACK vlc_timer_do (void *val, BOOLEAN timeout)
{
- vlc_timer_t *id = val;
+ struct vlc_timer *timer = val;
assert (timeout);
- if (TryEnterCriticalSection (&id->serializer))
- {
- id->overrun = InterlockedExchange (&id->counter, 0);
- id->func (id->data);
- LeaveCriticalSection (&id->serializer);
- }
- else /* Overrun */
- InterlockedIncrement (&id->counter);
+ timer->func (timer->data);
}
int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
{
- id->func = func;
- id->data = data;
- id->overrun = 0;
- id->handle = INVALID_HANDLE_VALUE;
- InitializeCriticalSection (&id->serializer);
+ struct vlc_timer *timer = malloc (sizeof (*timer));
+
+ if (timer == NULL)
+ return ENOMEM;
+ timer->func = func;
+ timer->data = data;
+ timer->handle = INVALID_HANDLE_VALUE;
+ *id = timer;
return 0;
}
-void vlc_timer_destroy (vlc_timer_t *id)
+void vlc_timer_destroy (vlc_timer_t timer)
{
- if (id->handle != INVALID_HANDLE_VALUE)
- DeleteTimerQueueTimer (NULL, id->handle, NULL);
- DeleteCriticalSection (&id->serializer);
+ if (timer->handle != INVALID_HANDLE_VALUE)
+ DeleteTimerQueueTimer (NULL, timer->handle, INVALID_HANDLE_VALUE);
+ free (timer);
}
-void vlc_timer_schedule (vlc_timer_t *id, bool absolute,
+void vlc_timer_schedule (vlc_timer_t timer, bool absolute,
mtime_t value, mtime_t interval)
{
- if (id->handle != INVALID_HANDLE_VALUE)
+ if (timer->handle != INVALID_HANDLE_VALUE)
{
- DeleteTimerQueueTimer (NULL, id->handle, NULL);
- id->handle = INVALID_HANDLE_VALUE;
+ DeleteTimerQueueTimer (NULL, timer->handle, NULL);
+ timer->handle = INVALID_HANDLE_VALUE;
}
if (value == 0)
return; /* Disarm */
value -= mdate ();
value = (value + 999) / 1000;
interval = (interval + 999) / 1000;
- if (!CreateTimerQueueTimer (&id->handle, NULL, vlc_timer_do, id, value,
- interval, WT_EXECUTEDEFAULT))
+ if (!CreateTimerQueueTimer (&timer->handle, NULL, vlc_timer_do, timer,
+ value, interval, WT_EXECUTEDEFAULT))
abort ();
}
-unsigned vlc_timer_getoverrun (const vlc_timer_t *id)
+unsigned vlc_timer_getoverrun (vlc_timer_t timer)
{
- return id->overrun;
+ (void)timer;
+ return 0;
}