#include <process.h>
#endif
-/* options */
-#ifndef _PY_USE_CV_LOCKS
-#define _PY_USE_CV_LOCKS 1 /* use locks based on cond vars */
-#endif
-
-/* Now, define a non-recursive mutex using either condition variables
- * and critical sections (fast) or using operating system mutexes
- * (slow)
- */
-
-#if _PY_USE_CV_LOCKS
-
-#include "condvar.h"
-
-typedef struct _NRMUTEX
-{
- PyMUTEX_T cs;
- PyCOND_T cv;
- int locked;
-} NRMUTEX;
-typedef NRMUTEX *PNRMUTEX;
-
-static PNRMUTEX
-AllocNonRecursiveMutex(void)
-{
- PNRMUTEX m = (PNRMUTEX)PyMem_RawMalloc(sizeof(NRMUTEX));
- if (!m)
- return NULL;
- if (PyCOND_INIT(&m->cv))
- goto fail;
- if (PyMUTEX_INIT(&m->cs)) {
- PyCOND_FINI(&m->cv);
- goto fail;
- }
- m->locked = 0;
- return m;
-fail:
- PyMem_RawFree(m);
- return NULL;
-}
-
-static VOID
-FreeNonRecursiveMutex(PNRMUTEX mutex)
-{
- if (mutex) {
- PyCOND_FINI(&mutex->cv);
- PyMUTEX_FINI(&mutex->cs);
- PyMem_RawFree(mutex);
- }
-}
-
-static DWORD
-EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
-{
- DWORD result = WAIT_OBJECT_0;
- if (PyMUTEX_LOCK(&mutex->cs))
- return WAIT_FAILED;
- if (milliseconds == INFINITE) {
- while (mutex->locked) {
- if (PyCOND_WAIT(&mutex->cv, &mutex->cs)) {
- result = WAIT_FAILED;
- break;
- }
- }
- } else if (milliseconds != 0) {
- /* wait at least until the deadline */
- PyTime_t timeout = (PyTime_t)milliseconds * (1000 * 1000);
- PyTime_t deadline = _PyDeadline_Init(timeout);
- while (mutex->locked) {
- PyTime_t microseconds = _PyTime_AsMicroseconds(timeout,
- _PyTime_ROUND_TIMEOUT);
- if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) {
- result = WAIT_FAILED;
- break;
- }
-
- timeout = _PyDeadline_Get(deadline);
- if (timeout <= 0) {
- break;
- }
- }
- }
- if (!mutex->locked) {
- mutex->locked = 1;
- result = WAIT_OBJECT_0;
- } else if (result == WAIT_OBJECT_0)
- result = WAIT_TIMEOUT;
- /* else, it is WAIT_FAILED */
- PyMUTEX_UNLOCK(&mutex->cs); /* must ignore result here */
- return result;
-}
-
-static BOOL
-LeaveNonRecursiveMutex(PNRMUTEX mutex)
-{
- BOOL result;
- if (PyMUTEX_LOCK(&mutex->cs))
- return FALSE;
- mutex->locked = 0;
- /* condvar APIs return 0 on success. We need to return TRUE on success. */
- result = !PyCOND_SIGNAL(&mutex->cv);
- PyMUTEX_UNLOCK(&mutex->cs);
- return result;
-}
-
-#else /* if ! _PY_USE_CV_LOCKS */
-
-/* NR-locks based on a kernel mutex */
-#define PNRMUTEX HANDLE
-
-static PNRMUTEX
-AllocNonRecursiveMutex(void)
-{
- return CreateSemaphore(NULL, 1, 1, NULL);
-}
-
-static VOID
-FreeNonRecursiveMutex(PNRMUTEX mutex)
-{
- /* No in-use check */
- CloseHandle(mutex);
-}
-
-static DWORD
-EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
-{
- return WaitForSingleObjectEx(mutex, milliseconds, FALSE);
-}
-
-static BOOL
-LeaveNonRecursiveMutex(PNRMUTEX mutex)
-{
- return ReleaseSemaphore(mutex, 1, NULL);
-}
-#endif /* _PY_USE_CV_LOCKS */
-
unsigned long PyThread_get_thread_ident(void);
#ifdef PY_HAVE_THREAD_NATIVE_ID