[Python-checkins] bpo-39511: Fix multiprocessing semlock_acquire() (GH-18298)

Victor Stinner webhook-mailer at python.org
Fri Jan 31 19:26:18 EST 2020


https://github.com/python/cpython/commit/7dc140126e918cc7c6e65aea321b7255f0020798
commit: 7dc140126e918cc7c6e65aea321b7255f0020798
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-02-01T01:25:59+01:00
summary:

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.

files:
M Modules/_multiprocessing/semaphore.c

diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c
index 4be2deae37750..ee490256d2a27 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 {



More information about the Python-checkins mailing list