diff options
author | Antoine Pitrou <pitrou@free.fr> | 2017-10-22 11:10:46 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-22 11:10:46 (GMT) |
commit | c872d39d324cd6f1a71b73e10406bbaed192d35f (patch) | |
tree | 3b3253f35177f1cfd0af8036290d8074e8b9cf50 /Modules | |
parent | bcbdd2f8db396c3f0ec9186162b39b5a34effa0e (diff) | |
download | cpython-c872d39d324cd6f1a71b73e10406bbaed192d35f.zip cpython-c872d39d324cd6f1a71b73e10406bbaed192d35f.tar.gz cpython-c872d39d324cd6f1a71b73e10406bbaed192d35f.tar.bz2 |
bpo-31653: Don't release the GIL if we can acquire a multiprocessing semaphore immediately (#4078)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_multiprocessing/semaphore.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index 79e8715..337e894 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -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; |