summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-10-22 11:10:46 (GMT)
committerGitHub <noreply@github.com>2017-10-22 11:10:46 (GMT)
commitc872d39d324cd6f1a71b73e10406bbaed192d35f (patch)
tree3b3253f35177f1cfd0af8036290d8074e8b9cf50
parentbcbdd2f8db396c3f0ec9186162b39b5a34effa0e (diff)
downloadcpython-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)
-rw-r--r--Misc/NEWS.d/next/Library/2017-10-22-12-43-03.bpo-31653.ttfGvq.rst2
-rw-r--r--Modules/_multiprocessing/semaphore.c30
2 files changed, 22 insertions, 10 deletions
diff --git a/Misc/NEWS.d/next/Library/2017-10-22-12-43-03.bpo-31653.ttfGvq.rst b/Misc/NEWS.d/next/Library/2017-10-22-12-43-03.bpo-31653.ttfGvq.rst
new file mode 100644
index 0000000..0587a08
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-10-22-12-43-03.bpo-31653.ttfGvq.rst
@@ -0,0 +1,2 @@
+Don't release the GIL if we can acquire a multiprocessing semaphore
+immediately.
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;