summaryrefslogtreecommitdiffstats
path: root/Python/condvar.h
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2017-09-06 04:43:08 (GMT)
committerGitHub <noreply@github.com>2017-09-06 04:43:08 (GMT)
commit05351c1bd8b70d1878527762174cdaaba3572395 (patch)
treee97ef4ba0ae7ffe5bd2c8969199616bffbbc4d6f /Python/condvar.h
parent833860615bedfd2484ac0623d6f01ff0578ba09f (diff)
downloadcpython-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.h75
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_ */