summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-02-01 00:25:59 (GMT)
committerGitHub <noreply@github.com>2020-02-01 00:25:59 (GMT)
commit7dc140126e918cc7c6e65aea321b7255f0020798 (patch)
treeaa97e02155e19af3b06f4d6b101c4002f37a7497
parentf03a8f8d5001963ad5b5b28dbd95497e9cc15596 (diff)
downloadcpython-7dc140126e918cc7c6e65aea321b7255f0020798.zip
cpython-7dc140126e918cc7c6e65aea321b7255f0020798.tar.gz
cpython-7dc140126e918cc7c6e65aea321b7255f0020798.tar.bz2
bpo-39511: Fix multiprocessing semlock_acquire() (GH-18298)
The Python C API must not be used when the GIL is released: only access Py_None when the GIL is hold.
-rw-r--r--Modules/_multiprocessing/semaphore.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c
index 4be2dea..ee49025 100644
--- a/Modules/_multiprocessing/semaphore.c
+++ b/Modules/_multiprocessing/semaphore.c
@@ -268,11 +268,8 @@ static PyObject *
semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
{
int blocking = 1, res, err = 0;
- double timeout;
PyObject *timeout_obj = Py_None;
struct timespec deadline = {0};
- struct timeval now;
- long sec, nsec;
static char *kwlist[] = {"block", "timeout", NULL};
@@ -285,19 +282,23 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
Py_RETURN_TRUE;
}
- if (timeout_obj != Py_None) {
- timeout = PyFloat_AsDouble(timeout_obj);
- if (PyErr_Occurred())
+ int use_deadline = (timeout_obj != Py_None);
+ if (use_deadline) {
+ double timeout = PyFloat_AsDouble(timeout_obj);
+ if (PyErr_Occurred()) {
return NULL;
- if (timeout < 0.0)
+ }
+ if (timeout < 0.0) {
timeout = 0.0;
+ }
+ struct timeval now;
if (gettimeofday(&now, NULL) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
- sec = (long) timeout;
- nsec = (long) (1e9 * (timeout - sec) + 0.5);
+ long sec = (long) timeout;
+ long nsec = (long) (1e9 * (timeout - sec) + 0.5);
deadline.tv_sec = now.tv_sec + sec;
deadline.tv_nsec = now.tv_usec * 1000 + nsec;
deadline.tv_sec += (deadline.tv_nsec / 1000000000);
@@ -315,7 +316,7 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
/* Couldn't acquire immediately, need to block */
do {
Py_BEGIN_ALLOW_THREADS
- if (timeout_obj == Py_None) {
+ if (!use_deadline) {
res = sem_wait(self->handle);
}
else {