bpo-31653: Don't release the GIL if we can acquire a multiprocessing semaphore immediately (#4078)

This commit is contained in:
Antoine Pitrou 2017-10-22 13:10:46 +02:00 committed by GitHub
parent bcbdd2f8db
commit c872d39d32
2 changed files with 22 additions and 10 deletions

View File

@ -0,0 +1,2 @@
Don't release the GIL if we can acquire a multiprocessing semaphore
immediately.

View File

@ -304,19 +304,29 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
deadline.tv_nsec %= 1000000000;
}
/* Check whether we can acquire without releasing the GIL and blocking */
do {
Py_BEGIN_ALLOW_THREADS
if (blocking && timeout_obj == Py_None)
res = sem_wait(self->handle);
else if (!blocking)
res = sem_trywait(self->handle);
else
res = sem_timedwait(self->handle, &deadline);
Py_END_ALLOW_THREADS
res = sem_trywait(self->handle);
err = errno;
if (res == MP_EXCEPTION_HAS_BEEN_SET)
break;
} while (res < 0 && errno == EINTR && !PyErr_CheckSignals());
errno = err;
if (res < 0 && errno == EAGAIN && blocking) {
/* Couldn't acquire immediately, need to block */
do {
Py_BEGIN_ALLOW_THREADS
if (blocking && timeout_obj == Py_None)
res = sem_wait(self->handle);
else if (!blocking)
res = sem_trywait(self->handle);
else
res = sem_timedwait(self->handle, &deadline);
Py_END_ALLOW_THREADS
err = errno;
if (res == MP_EXCEPTION_HAS_BEEN_SET)
break;
} while (res < 0 && errno == EINTR && !PyErr_CheckSignals());
}
if (res < 0) {
errno = err;