Skip to content

Commit

Permalink
bpo-39511: Fix multiprocessing semlock_acquire() (pythonGH-18298)
Browse files Browse the repository at this point in the history
The Python C API must not be used when the GIL is released: only
access Py_None when the GIL is hold.
  • Loading branch information
vstinner committed Feb 1, 2020
1 parent f03a8f8 commit 7dc1401
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions Modules/_multiprocessing/semaphore.c
Expand Up @@ -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};

Expand All @@ -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);
Expand All @@ -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 {
Expand Down

0 comments on commit 7dc1401

Please sign in to comment.