Skip to content

Commit 7dc1401

Browse files
authored
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.
1 parent f03a8f8 commit 7dc1401

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

Modules/_multiprocessing/semaphore.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,8 @@ static PyObject *
268268
semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
269269
{
270270
int blocking = 1, res, err = 0;
271-
double timeout;
272271
PyObject *timeout_obj = Py_None;
273272
struct timespec deadline = {0};
274-
struct timeval now;
275-
long sec, nsec;
276273

277274
static char *kwlist[] = {"block", "timeout", NULL};
278275

@@ -285,19 +282,23 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
285282
Py_RETURN_TRUE;
286283
}
287284

288-
if (timeout_obj != Py_None) {
289-
timeout = PyFloat_AsDouble(timeout_obj);
290-
if (PyErr_Occurred())
285+
int use_deadline = (timeout_obj != Py_None);
286+
if (use_deadline) {
287+
double timeout = PyFloat_AsDouble(timeout_obj);
288+
if (PyErr_Occurred()) {
291289
return NULL;
292-
if (timeout < 0.0)
290+
}
291+
if (timeout < 0.0) {
293292
timeout = 0.0;
293+
}
294294

295+
struct timeval now;
295296
if (gettimeofday(&now, NULL) < 0) {
296297
PyErr_SetFromErrno(PyExc_OSError);
297298
return NULL;
298299
}
299-
sec = (long) timeout;
300-
nsec = (long) (1e9 * (timeout - sec) + 0.5);
300+
long sec = (long) timeout;
301+
long nsec = (long) (1e9 * (timeout - sec) + 0.5);
301302
deadline.tv_sec = now.tv_sec + sec;
302303
deadline.tv_nsec = now.tv_usec * 1000 + nsec;
303304
deadline.tv_sec += (deadline.tv_nsec / 1000000000);
@@ -315,7 +316,7 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
315316
/* Couldn't acquire immediately, need to block */
316317
do {
317318
Py_BEGIN_ALLOW_THREADS
318-
if (timeout_obj == Py_None) {
319+
if (!use_deadline) {
319320
res = sem_wait(self->handle);
320321
}
321322
else {

0 commit comments

Comments
 (0)