diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2017-09-06 04:43:08 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-06 04:43:08 (GMT) |
commit | 05351c1bd8b70d1878527762174cdaaba3572395 (patch) | |
tree | e97ef4ba0ae7ffe5bd2c8969199616bffbbc4d6f /Python/condvar.h | |
parent | 833860615bedfd2484ac0623d6f01ff0578ba09f (diff) | |
download | cpython-05351c1bd8b70d1878527762174cdaaba3572395.zip cpython-05351c1bd8b70d1878527762174cdaaba3572395.tar.gz cpython-05351c1bd8b70d1878527762174cdaaba3572395.tar.bz2 |
Revert "bpo-30860: Consolidate stateful runtime globals." (#3379)
Windows buildbots started failing due to include-related errors.
Diffstat (limited to 'Python/condvar.h')
-rw-r--r-- | Python/condvar.h | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/Python/condvar.h b/Python/condvar.h index aaa8043..9a71b17 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -37,16 +37,27 @@ * Condition Variable. */ -#ifndef _CONDVAR_IMPL_H_ -#define _CONDVAR_IMPL_H_ +#ifndef _CONDVAR_H_ +#define _CONDVAR_H_ #include "Python.h" -#include "internal/_condvar.h" + +#ifndef _POSIX_THREADS +/* This means pthreads are not implemented in libc headers, hence the macro + not present in unistd.h. But they still can be implemented as an external + library (e.g. gnu pth in pthread emulation) */ +# ifdef HAVE_PTHREAD_H +# include <pthread.h> /* _POSIX_THREADS */ +# endif +#endif #ifdef _POSIX_THREADS /* * POSIX support */ +#define Py_HAVE_CONDVAR + +#include <pthread.h> #define PyCOND_ADD_MICROSECONDS(tv, interval) \ do { /* TODO: add overflow and truncation checks */ \ @@ -63,11 +74,13 @@ do { /* TODO: add overflow and truncation checks */ \ #endif /* The following functions return 0 on success, nonzero on error */ +#define PyMUTEX_T pthread_mutex_t #define PyMUTEX_INIT(mut) pthread_mutex_init((mut), NULL) #define PyMUTEX_FINI(mut) pthread_mutex_destroy(mut) #define PyMUTEX_LOCK(mut) pthread_mutex_lock(mut) #define PyMUTEX_UNLOCK(mut) pthread_mutex_unlock(mut) +#define PyCOND_T pthread_cond_t #define PyCOND_INIT(cond) pthread_cond_init((cond), NULL) #define PyCOND_FINI(cond) pthread_cond_destroy(cond) #define PyCOND_SIGNAL(cond) pthread_cond_signal(cond) @@ -103,11 +116,45 @@ PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) * Emulated condition variables ones that work with XP and later, plus * example native support on VISTA and onwards. */ +#define Py_HAVE_CONDVAR + + +/* include windows if it hasn't been done before */ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +/* options */ +/* non-emulated condition variables are provided for those that want + * to target Windows Vista. Modify this macro to enable them. + */ +#ifndef _PY_EMULATED_WIN_CV +#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */ +#endif + +/* fall back to emulation if not targeting Vista */ +#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA +#undef _PY_EMULATED_WIN_CV +#define _PY_EMULATED_WIN_CV 1 +#endif + #if _PY_EMULATED_WIN_CV /* The mutex is a CriticalSection object and The condition variables is emulated with the help of a semaphore. + Semaphores are available on Windows XP (2003 server) and later. + We use a Semaphore rather than an auto-reset event, because although + an auto-resent event might appear to solve the lost-wakeup bug (race + condition between releasing the outer lock and waiting) because it + maintains state even though a wait hasn't happened, there is still + a lost wakeup problem if more than one thread are interrupted in the + critical place. A semaphore solves that, because its state is counted, + not Boolean. + Because it is ok to signal a condition variable with no one + waiting, we need to keep track of the number of + waiting threads. Otherwise, the semaphore's state could rise + without bound. This also helps reduce the number of "spurious wakeups" + that would otherwise happen. This implementation still has the problem that the threads woken with a "signal" aren't necessarily those that are already @@ -121,6 +168,8 @@ PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) http://www.cse.wustl.edu/~schmidt/win32-cv-1.html */ +typedef CRITICAL_SECTION PyMUTEX_T; + Py_LOCAL_INLINE(int) PyMUTEX_INIT(PyMUTEX_T *cs) { @@ -149,6 +198,15 @@ PyMUTEX_UNLOCK(PyMUTEX_T *cs) return 0; } +/* The ConditionVariable object. From XP onwards it is easily emulated with + * a Semaphore + */ + +typedef struct _PyCOND_T +{ + HANDLE sem; + int waiting; /* to allow PyCOND_SIGNAL to be a no-op */ +} PyCOND_T; Py_LOCAL_INLINE(int) PyCOND_INIT(PyCOND_T *cv) @@ -246,7 +304,12 @@ PyCOND_BROADCAST(PyCOND_T *cv) return 0; } -#else /* !_PY_EMULATED_WIN_CV */ +#else + +/* Use native Win7 primitives if build target is Win7 or higher */ + +/* SRWLOCK is faster and better than CriticalSection */ +typedef SRWLOCK PyMUTEX_T; Py_LOCAL_INLINE(int) PyMUTEX_INIT(PyMUTEX_T *cs) @@ -276,6 +339,8 @@ PyMUTEX_UNLOCK(PyMUTEX_T *cs) } +typedef CONDITION_VARIABLE PyCOND_T; + Py_LOCAL_INLINE(int) PyCOND_INIT(PyCOND_T *cv) { @@ -322,4 +387,4 @@ PyCOND_BROADCAST(PyCOND_T *cv) #endif /* _POSIX_THREADS, NT_THREADS */ -#endif /* _CONDVAR_IMPL_H_ */ +#endif /* _CONDVAR_H_ */ |