Skip to content

Commit c872d39

Browse files
authored
bpo-31653: Don't release the GIL if we can acquire a multiprocessing semaphore immediately (#4078)
1 parent bcbdd2f commit c872d39

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Don't release the GIL if we can acquire a multiprocessing semaphore
2+
immediately.

Modules/_multiprocessing/semaphore.c

+20-10
Original file line numberDiff line numberDiff line change
@@ -304,19 +304,29 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
304304
deadline.tv_nsec %= 1000000000;
305305
}
306306

307+
/* Check whether we can acquire without releasing the GIL and blocking */
307308
do {
308-
Py_BEGIN_ALLOW_THREADS
309-
if (blocking && timeout_obj == Py_None)
310-
res = sem_wait(self->handle);
311-
else if (!blocking)
312-
res = sem_trywait(self->handle);
313-
else
314-
res = sem_timedwait(self->handle, &deadline);
315-
Py_END_ALLOW_THREADS
309+
res = sem_trywait(self->handle);
316310
err = errno;
317-
if (res == MP_EXCEPTION_HAS_BEEN_SET)
318-
break;
319311
} while (res < 0 && errno == EINTR && !PyErr_CheckSignals());
312+
errno = err;
313+
314+
if (res < 0 && errno == EAGAIN && blocking) {
315+
/* Couldn't acquire immediately, need to block */
316+
do {
317+
Py_BEGIN_ALLOW_THREADS
318+
if (blocking && timeout_obj == Py_None)
319+
res = sem_wait(self->handle);
320+
else if (!blocking)
321+
res = sem_trywait(self->handle);
322+
else
323+
res = sem_timedwait(self->handle, &deadline);
324+
Py_END_ALLOW_THREADS
325+
err = errno;
326+
if (res == MP_EXCEPTION_HAS_BEEN_SET)
327+
break;
328+
} while (res < 0 && errno == EINTR && !PyErr_CheckSignals());
329+
}
320330

321331
if (res < 0) {
322332
errno = err;

0 commit comments

Comments
 (0)