[vlc-commits] Win32: refactor thread wait & sleep support
Rémi Denis-Courmont
git at videolan.org
Sat Jul 23 10:58:31 CEST 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Jul 23 11:20:00 2011 +0300| [e424248a63b6122c70f7360c5cfe882e6784795c] | committer: Rémi Denis-Courmont
Win32: refactor thread wait & sleep support
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e424248a63b6122c70f7360c5cfe882e6784795c
---
src/win32/thread.c | 125 ++++++++++++++++++++++------------------------------
1 files changed, 53 insertions(+), 72 deletions(-)
diff --git a/src/win32/thread.c b/src/win32/thread.c
index 7ced22d..1da6020 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -64,79 +64,36 @@ struct vlc_thread
#ifdef UNDER_CE
static void CALLBACK vlc_cancel_self (ULONG_PTR dummy);
-static DWORD vlc_cancelable_wait (DWORD count, const HANDLE *handles,
- DWORD delay)
-{
- struct vlc_thread *th = vlc_threadvar_get (thread_key);
- if (th == NULL)
- {
- /* Main thread - cannot be cancelled anyway */
- return WaitForMultipleObjects (count, handles, FALSE, delay);
- }
- HANDLE new_handles[count + 1];
- memcpy(new_handles, handles, count * sizeof(HANDLE));
- new_handles[count] = th->cancel_event;
- DWORD result = WaitForMultipleObjects (count + 1, new_handles, FALSE,
- delay);
- if (result == WAIT_OBJECT_0 + count)
- {
- vlc_cancel_self ((uintptr_t)th);
- return WAIT_IO_COMPLETION;
- }
- else
- {
- return result;
- }
-}
-
-DWORD SleepEx (DWORD dwMilliseconds, BOOL bAlertable)
-{
- if (bAlertable)
- {
- DWORD result = vlc_cancelable_wait (0, NULL, dwMilliseconds);
- return (result == WAIT_TIMEOUT) ? 0 : WAIT_IO_COMPLETION;
- }
- else
- {
- Sleep(dwMilliseconds);
- return 0;
- }
-}
-
-DWORD WaitForSingleObjectEx (HANDLE hHandle, DWORD dwMilliseconds,
- BOOL bAlertable)
-{
- if (bAlertable)
- {
- /* The MSDN documentation specifies different return codes,
- * but in practice they are the same. We just check that it
- * remains so. */
-#if WAIT_ABANDONED != WAIT_ABANDONED_0
-# error Windows headers changed, code needs to be rewritten!
-#endif
- return vlc_cancelable_wait (1, &hHandle, dwMilliseconds);
- }
- else
- {
- return WaitForSingleObject (hHandle, dwMilliseconds);
- }
-}
-
DWORD WaitForMultipleObjectsEx (DWORD nCount, const HANDLE *lpHandles,
BOOL bWaitAll, DWORD dwMilliseconds,
BOOL bAlertable)
{
+ HANDLE handles[nCount + 1];
+ DWORD ret;
+
+ memcpy(handles, lpHandles, count * sizeof(HANDLE));
if (bAlertable)
{
- /* We do not support the bWaitAll case */
- assert (! bWaitAll);
- return vlc_cancelable_wait (nCount, lpHandles, dwMilliseconds);
+ struct vlc_thread *th = vlc_threadvar_get (thread_key);
+ if (th != NULL)
+ {
+ handles[nCount] = th->cancel_event;
+ /* bWaitAll not implemented and not used by VLC... */
+ assert (!bWaitAll);
+ }
+ else
+ bAltertable = FALSE;
}
- else
+
+ ret = WaitForMultipleObjects (nCount + bAlertable, handles, bWaitAll,
+ dwMilliseconds);
+ if (ret == WAIT_OBJECT_0 + nCount)
{
- return WaitForMultipleObjects (nCount, lpHandles, bWaitAll,
- dwMilliseconds);
+ assert (bAlertable);
+ vlc_cancel_self ((uintptr_t)th);
+ ret = WAIT_IO_COMPLETION;
}
+ return ret;
}
#endif
@@ -167,6 +124,34 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
return TRUE;
}
+static DWORD vlc_WaitForMultipleObjects (DWORD count, const HANDLE *handles,
+ DWORD delay)
+{
+ DWORD ret = WaitForMultipleObjectsEx (count, handles, FALSE, delay, TRUE);
+
+ /* We do not abandon objects... this would be a bug */
+ assert (ret < WAIT_ABANDONED_0 || WAIT_ABANDONED_0 + count - 1 < ret);
+
+ if (unlikely(ret == WAIT_FAILED))
+ abort (); /* We are screwed! */
+
+ return ret;
+}
+
+static DWORD vlc_WaitForSingleObject (HANDLE handle, DWORD delay)
+{
+ return vlc_WaitForMultipleObjects (1, &handle, delay);
+}
+
+static DWORD vlc_Sleep (DWORD delay)
+{
+ DWORD ret = vlc_WaitForMultipleObjects (0, NULL, delay);
+ if (ret == WAIT_TIMEOUT)
+ ret = 0;
+ return ret;
+}
+
+
/*** Mutexes ***/
void vlc_mutex_init( vlc_mutex_t *p_mutex )
{
@@ -305,13 +290,11 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
{
vlc_testcancel ();
LeaveCriticalSection (&p_mutex->mutex);
- result = WaitForSingleObjectEx (p_condvar->handle, INFINITE, TRUE);
+ result = vlc_WaitForSingleObject (p_condvar->handle, INFINITE);
EnterCriticalSection (&p_mutex->mutex);
}
while (result == WAIT_IO_COMPLETION);
- assert (result != WAIT_ABANDONED); /* another thread failed to cleanup! */
- assert (result != WAIT_FAILED);
ResetEvent (p_condvar->handle);
}
@@ -342,13 +325,11 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
DWORD delay = (total > 0x7fffffff) ? 0x7fffffff : total;
LeaveCriticalSection (&p_mutex->mutex);
- result = WaitForSingleObjectEx (p_condvar->handle, delay, TRUE);
+ result = vlc_WaitForSingleObject (p_condvar->handle, delay);
EnterCriticalSection (&p_mutex->mutex);
}
while (result == WAIT_IO_COMPLETION);
- assert (result != WAIT_ABANDONED);
- assert (result != WAIT_FAILED);
ResetEvent (p_condvar->handle);
return (result == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
@@ -380,7 +361,7 @@ void vlc_sem_wait (vlc_sem_t *sem)
do
{
vlc_testcancel ();
- result = WaitForSingleObjectEx (*sem, INFINITE, TRUE);
+ result = vlc_WaitForSingleObject (*sem, INFINITE);
}
while (result == WAIT_IO_COMPLETION);
}
@@ -808,7 +789,7 @@ void mwait (mtime_t deadline)
delay /= 1000;
if (unlikely(delay > 0x7fffffff))
delay = 0x7fffffff;
- SleepEx (delay, TRUE);
+ vlc_Sleep (delay);
vlc_testcancel();
}
}
More information about the vlc-commits
mailing list