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.
This commit is contained in:
parent
f03a8f8d50
commit
7dc140126e
@ -268,11 +268,8 @@ static PyObject *
|
|||||||
semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
|
semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
int blocking = 1, res, err = 0;
|
int blocking = 1, res, err = 0;
|
||||||
double timeout;
|
|
||||||
PyObject *timeout_obj = Py_None;
|
PyObject *timeout_obj = Py_None;
|
||||||
struct timespec deadline = {0};
|
struct timespec deadline = {0};
|
||||||
struct timeval now;
|
|
||||||
long sec, nsec;
|
|
||||||
|
|
||||||
static char *kwlist[] = {"block", "timeout", NULL};
|
static char *kwlist[] = {"block", "timeout", NULL};
|
||||||
|
|
||||||
@ -285,19 +282,23 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
|
|||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout_obj != Py_None) {
|
int use_deadline = (timeout_obj != Py_None);
|
||||||
timeout = PyFloat_AsDouble(timeout_obj);
|
if (use_deadline) {
|
||||||
if (PyErr_Occurred())
|
double timeout = PyFloat_AsDouble(timeout_obj);
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
if (timeout < 0.0)
|
}
|
||||||
|
if (timeout < 0.0) {
|
||||||
timeout = 0.0;
|
timeout = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timeval now;
|
||||||
if (gettimeofday(&now, NULL) < 0) {
|
if (gettimeofday(&now, NULL) < 0) {
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sec = (long) timeout;
|
long sec = (long) timeout;
|
||||||
nsec = (long) (1e9 * (timeout - sec) + 0.5);
|
long nsec = (long) (1e9 * (timeout - sec) + 0.5);
|
||||||
deadline.tv_sec = now.tv_sec + sec;
|
deadline.tv_sec = now.tv_sec + sec;
|
||||||
deadline.tv_nsec = now.tv_usec * 1000 + nsec;
|
deadline.tv_nsec = now.tv_usec * 1000 + nsec;
|
||||||
deadline.tv_sec += (deadline.tv_nsec / 1000000000);
|
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 */
|
/* Couldn't acquire immediately, need to block */
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
if (timeout_obj == Py_None) {
|
if (!use_deadline) {
|
||||||
res = sem_wait(self->handle);
|
res = sem_wait(self->handle);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user