diff options
author | Victor Stinner <vstinner@python.org> | 2020-02-01 00:25:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-01 00:25:59 (GMT) |
commit | 7dc140126e918cc7c6e65aea321b7255f0020798 (patch) | |
tree | aa97e02155e19af3b06f4d6b101c4002f37a7497 | |
parent | f03a8f8d5001963ad5b5b28dbd95497e9cc15596 (diff) | |
download | cpython-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.c | 21 |
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 { |