-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] bpo-32592: Drop support for Windows Vista #5231
Changes from 2 commits
1a83ced
7dc2b5d
764f4a8
747ee70
1ed070d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,70 +22,18 @@ | |
#define PyCOND_T pthread_cond_t | ||
|
||
#elif defined(NT_THREADS) | ||
/* | ||
* Windows (XP, 2003 server and later, as well as (hopefully) CE) support | ||
* | ||
* Emulated condition variables ones that work with XP and later, plus | ||
* example native support on VISTA and onwards. | ||
*/ | ||
/* Windows support: use native Win7 primitives */ | ||
#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 */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't removing this a mistake? I think the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hum, this code seems to sensitive and my change may conflict with https://bugs.python.org/issue29871 so I reverted this change and will open a new dedicated PR. |
||
#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 | ||
|
||
typedef CRITICAL_SECTION PyMUTEX_T; | ||
|
||
/* The ConditionVariable object. From XP onwards it is easily emulated | ||
with 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. | ||
*/ | ||
|
||
typedef struct _PyCOND_T | ||
{ | ||
HANDLE sem; | ||
int waiting; /* to allow PyCOND_SIGNAL to be a no-op */ | ||
} PyCOND_T; | ||
|
||
#else /* !_PY_EMULATED_WIN_CV */ | ||
|
||
/* Use native Win7 primitives if build target is Win7 or higher */ | ||
|
||
/* SRWLOCK is faster and better than CriticalSection */ | ||
typedef SRWLOCK PyMUTEX_T; | ||
|
||
typedef CONDITION_VARIABLE PyCOND_T; | ||
|
||
#endif /* _PY_EMULATED_WIN_CV */ | ||
|
||
#endif /* _POSIX_THREADS, NT_THREADS */ | ||
|
||
#endif /* Py_INTERNAL_CONDVAR_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Drop support for Windows Vista. Windows Vista extended support ended in | ||
April 2017. As stated in :pep:`11`, Python 3.7 drops support for Windows | ||
Vista and now requires Windows 7 or newer. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,156 +97,6 @@ PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) | |
} | ||
|
||
#elif defined(NT_THREADS) | ||
/* | ||
* Windows (XP, 2003 server and later, as well as (hopefully) CE) support | ||
* | ||
* Emulated condition variables ones that work with XP and later, plus | ||
* example native support on VISTA and onwards. | ||
*/ | ||
|
||
#if _PY_EMULATED_WIN_CV | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See https://bugs.python.org/issue29871 before pulling this code out - our alternate code isn't 100% correct yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I can revert this change and propose it in https://bugs.python.org/issue29871. My change should have no effect on Windows 7 and newer. Why do you prefer to keep the unused emulation code (until bpo-29871 is fixed)? |
||
|
||
/* The mutex is a CriticalSection object and | ||
The condition variables is emulated with the help of a semaphore. | ||
|
||
This implementation still has the problem that the threads woken | ||
with a "signal" aren't necessarily those that are already | ||
waiting. It corresponds to listing 2 in: | ||
http://birrell.org/andrew/papers/ImplementingCVs.pdf | ||
|
||
Generic emulations of the pthread_cond_* API using | ||
earlier Win32 functions can be found on the Web. | ||
The following read can be give background information to these issues, | ||
but the implementations are all broken in some way. | ||
http://www.cse.wustl.edu/~schmidt/win32-cv-1.html | ||
*/ | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyMUTEX_INIT(PyMUTEX_T *cs) | ||
{ | ||
InitializeCriticalSection(cs); | ||
return 0; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyMUTEX_FINI(PyMUTEX_T *cs) | ||
{ | ||
DeleteCriticalSection(cs); | ||
return 0; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyMUTEX_LOCK(PyMUTEX_T *cs) | ||
{ | ||
EnterCriticalSection(cs); | ||
return 0; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyMUTEX_UNLOCK(PyMUTEX_T *cs) | ||
{ | ||
LeaveCriticalSection(cs); | ||
return 0; | ||
} | ||
|
||
|
||
Py_LOCAL_INLINE(int) | ||
PyCOND_INIT(PyCOND_T *cv) | ||
{ | ||
/* A semaphore with a "large" max value, The positive value | ||
* is only needed to catch those "lost wakeup" events and | ||
* race conditions when a timed wait elapses. | ||
*/ | ||
cv->sem = CreateSemaphore(NULL, 0, 100000, NULL); | ||
if (cv->sem==NULL) | ||
return -1; | ||
cv->waiting = 0; | ||
return 0; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyCOND_FINI(PyCOND_T *cv) | ||
{ | ||
return CloseHandle(cv->sem) ? 0 : -1; | ||
} | ||
|
||
/* this implementation can detect a timeout. Returns 1 on timeout, | ||
* 0 otherwise (and -1 on error) | ||
*/ | ||
Py_LOCAL_INLINE(int) | ||
_PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) | ||
{ | ||
DWORD wait; | ||
cv->waiting++; | ||
PyMUTEX_UNLOCK(cs); | ||
/* "lost wakeup bug" would occur if the caller were interrupted here, | ||
* but we are safe because we are using a semaphore which has an internal | ||
* count. | ||
*/ | ||
wait = WaitForSingleObjectEx(cv->sem, ms, FALSE); | ||
PyMUTEX_LOCK(cs); | ||
if (wait != WAIT_OBJECT_0) | ||
--cv->waiting; | ||
/* Here we have a benign race condition with PyCOND_SIGNAL. | ||
* When failure occurs or timeout, it is possible that | ||
* PyCOND_SIGNAL also decrements this value | ||
* and signals releases the mutex. This is benign because it | ||
* just means an extra spurious wakeup for a waiting thread. | ||
* ('waiting' corresponds to the semaphore's "negative" count and | ||
* we may end up with e.g. (waiting == -1 && sem.count == 1). When | ||
* a new thread comes along, it will pass right throuhgh, having | ||
* adjusted it to (waiting == 0 && sem.count == 0). | ||
*/ | ||
|
||
if (wait == WAIT_FAILED) | ||
return -1; | ||
/* return 0 on success, 1 on timeout */ | ||
return wait != WAIT_OBJECT_0; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) | ||
{ | ||
int result = _PyCOND_WAIT_MS(cv, cs, INFINITE); | ||
return result >= 0 ? 0 : result; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us) | ||
{ | ||
return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000)); | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyCOND_SIGNAL(PyCOND_T *cv) | ||
{ | ||
/* this test allows PyCOND_SIGNAL to be a no-op unless required | ||
* to wake someone up, thus preventing an unbounded increase of | ||
* the semaphore's internal counter. | ||
*/ | ||
if (cv->waiting > 0) { | ||
/* notifying thread decreases the cv->waiting count so that | ||
* a delay between notify and actual wakeup of the target thread | ||
* doesn't cause a number of extra ReleaseSemaphore calls. | ||
*/ | ||
cv->waiting--; | ||
return ReleaseSemaphore(cv->sem, 1, NULL) ? 0 : -1; | ||
} | ||
return 0; | ||
} | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyCOND_BROADCAST(PyCOND_T *cv) | ||
{ | ||
int waiting = cv->waiting; | ||
if (waiting > 0) { | ||
cv->waiting = 0; | ||
return ReleaseSemaphore(cv->sem, waiting, NULL) ? 0 : -1; | ||
} | ||
return 0; | ||
} | ||
|
||
#else /* !_PY_EMULATED_WIN_CV */ | ||
|
||
Py_LOCAL_INLINE(int) | ||
PyMUTEX_INIT(PyMUTEX_T *cs) | ||
|
@@ -317,9 +167,6 @@ PyCOND_BROADCAST(PyCOND_T *cv) | |
return 0; | ||
} | ||
|
||
|
||
#endif /* _PY_EMULATED_WIN_CV */ | ||
|
||
#endif /* _POSIX_THREADS, NT_THREADS */ | ||
|
||
#endif /* _CONDVAR_IMPL_H_ */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could change the comment before
#define Py_HAVE_CONDVAR
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in fact, should we remove all the references to Vista when we drop the support of Vista ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the comment.