https://github.com/python/cpython/commit/b3f0b698daf2438a6e59d5d19ccb34acdba0bffc
commit: b3f0b698daf2438a6e59d5d19ccb34acdba0bffc
branch: main
author: Andrew Rogers <[email protected]>
committer: zooba <[email protected]>
date: 2024-02-02T13:50:51Z
summary:

gh-104530: Enable native Win32 condition variables by default (GH-104531)

files:
A Misc/NEWS.d/next/Core and 
Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst
M Include/internal/pycore_condvar.h
M Python/ceval_gil.c
M Python/condvar.h
M Python/pystate.c
M Python/thread_nt.h

diff --git a/Include/internal/pycore_condvar.h 
b/Include/internal/pycore_condvar.h
index 34c21aaad43197..ee9533484e8048 100644
--- a/Include/internal/pycore_condvar.h
+++ b/Include/internal/pycore_condvar.h
@@ -35,14 +35,14 @@
 #include <windows.h>              // CRITICAL_SECTION
 
 /* options */
-/* non-emulated condition variables are provided for those that want
- * to target Windows Vista.  Modify this macro to enable them.
+/* emulated condition variables are provided for those that want
+ * to target Windows XP or earlier. Modify this macro to enable them.
  */
 #ifndef _PY_EMULATED_WIN_CV
-#define _PY_EMULATED_WIN_CV 1  /* use emulated condition variables */
+#define _PY_EMULATED_WIN_CV 0  /* use non-emulated condition variables */
 #endif
 
-/* fall back to emulation if not targeting Vista */
+/* fall back to emulation if targeting earlier than Vista */
 #if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA
 #undef _PY_EMULATED_WIN_CV
 #define _PY_EMULATED_WIN_CV 1
@@ -77,7 +77,7 @@ typedef struct _PyCOND_T
 
 #else /* !_PY_EMULATED_WIN_CV */
 
-/* Use native Win7 primitives if build target is Win7 or higher */
+/* Use native Windows primitives if build target is Vista or higher */
 
 /* SRWLOCK is faster and better than CriticalSection */
 typedef SRWLOCK PyMUTEX_T;
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst b/Misc/NEWS.d/next/Core 
and Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst
new file mode 100644
index 00000000000000..8643a25ae51b13
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst 
@@ -0,0 +1 @@
+Use native Win32 condition variables.
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c
index f3b169241535f3..ad90359318761a 100644
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -610,8 +610,16 @@ PyEval_SaveThread(void)
 void
 PyEval_RestoreThread(PyThreadState *tstate)
 {
+#ifdef MS_WINDOWS
+    int err = GetLastError();
+#endif
+
     _Py_EnsureTstateNotNULL(tstate);
     _PyThreadState_Attach(tstate);
+
+#ifdef MS_WINDOWS
+    SetLastError(err);
+#endif
 }
 
 
diff --git a/Python/condvar.h b/Python/condvar.h
index d54db94f2c871d..dcabed6d55928c 100644
--- a/Python/condvar.h
+++ b/Python/condvar.h
@@ -260,13 +260,13 @@ PyMUTEX_UNLOCK(PyMUTEX_T *cs)
     return 0;
 }
 
-
 Py_LOCAL_INLINE(int)
 PyCOND_INIT(PyCOND_T *cv)
 {
     InitializeConditionVariable(cv);
     return 0;
 }
+
 Py_LOCAL_INLINE(int)
 PyCOND_FINI(PyCOND_T *cv)
 {
@@ -279,27 +279,32 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs)
     return SleepConditionVariableSRW(cv, cs, INFINITE, 0) ? 0 : -1;
 }
 
-/* This implementation makes no distinction about timeouts.  Signal
- * 2 to indicate that we don't know.
- */
+/* return 0 for success, 1 on timeout, -1 on error */
 Py_LOCAL_INLINE(int)
 PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us)
 {
-    return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1;
+    BOOL success = SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0);
+    if (!success) {
+        if (GetLastError() == ERROR_TIMEOUT) {
+            return 1;
+        }
+        return -1;
+    }
+    return 0;
 }
 
 Py_LOCAL_INLINE(int)
 PyCOND_SIGNAL(PyCOND_T *cv)
 {
-     WakeConditionVariable(cv);
-     return 0;
+    WakeConditionVariable(cv);
+    return 0;
 }
 
 Py_LOCAL_INLINE(int)
 PyCOND_BROADCAST(PyCOND_T *cv)
 {
-     WakeAllConditionVariable(cv);
-     return 0;
+    WakeAllConditionVariable(cv);
+    return 0;
 }
 
 
diff --git a/Python/pystate.c b/Python/pystate.c
index 27b6d0573ade3b..7836c172bbfb61 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -2488,7 +2488,17 @@ PyGILState_Check(void)
         return 0;
     }
 
-    return (tstate == gilstate_tss_get(runtime));
+#ifdef MS_WINDOWS
+    int err = GetLastError();
+#endif
+
+    PyThreadState *tcur = gilstate_tss_get(runtime);
+
+#ifdef MS_WINDOWS
+    SetLastError(err);
+#endif
+
+    return (tstate == tcur);
 }
 
 PyGILState_STATE
diff --git a/Python/thread_nt.h b/Python/thread_nt.h
index 14b9cddc24c0ec..044e9fa111e979 100644
--- a/Python/thread_nt.h
+++ b/Python/thread_nt.h
@@ -444,16 +444,7 @@ PyThread_set_key_value(int key, void *value)
 void *
 PyThread_get_key_value(int key)
 {
-    /* because TLS is used in the Py_END_ALLOW_THREAD macro,
-     * it is necessary to preserve the windows error state, because
-     * it is assumed to be preserved across the call to the macro.
-     * Ideally, the macro should be fixed, but it is simpler to
-     * do it here.
-     */
-    DWORD error = GetLastError();
-    void *result = TlsGetValue(key);
-    SetLastError(error);
-    return result;
+    return TlsGetValue(key);
 }
 
 void
@@ -525,14 +516,5 @@ void *
 PyThread_tss_get(Py_tss_t *key)
 {
     assert(key != NULL);
-    /* because TSS is used in the Py_END_ALLOW_THREAD macro,
-     * it is necessary to preserve the windows error state, because
-     * it is assumed to be preserved across the call to the macro.
-     * Ideally, the macro should be fixed, but it is simpler to
-     * do it here.
-     */
-    DWORD error = GetLastError();
-    void *result = TlsGetValue(key->_key);
-    SetLastError(error);
-    return result;
+    return TlsGetValue(key->_key);
 }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to