summaryrefslogtreecommitdiffstats
path: root/Modules/_multiprocessing/semaphore.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_multiprocessing/semaphore.c')
-rw-r--r--Modules/_multiprocessing/semaphore.c59
1 files changed, 24 insertions, 35 deletions
diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c
index 1f37d6a..8ea92f2 100644
--- a/Modules/_multiprocessing/semaphore.c
+++ b/Modules/_multiprocessing/semaphore.c
@@ -3,7 +3,8 @@
*
* semaphore.c
*
- * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+ * Copyright (c) 2006-2008, R Oudkerk
+ * Licensed to PSF under a Contributor Agreement.
*/
#include "multiprocessing.h"
@@ -62,7 +63,8 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
int blocking = 1;
double timeout;
PyObject *timeout_obj = Py_None;
- DWORD res, full_msecs, msecs, start, ticks;
+ DWORD res, full_msecs, nhandles;
+ HANDLE handles[2], sigint_event;
static char *kwlist[] = {"block", "timeout", NULL};
@@ -96,53 +98,40 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
Py_RETURN_TRUE;
}
- /* check whether we can acquire without blocking */
+ /* check whether we can acquire without releasing the GIL and blocking */
if (WaitForSingleObject(self->handle, 0) == WAIT_OBJECT_0) {
self->last_tid = GetCurrentThreadId();
++self->count;
Py_RETURN_TRUE;
}
- msecs = full_msecs;
- start = GetTickCount();
-
- for ( ; ; ) {
- HANDLE handles[2] = {self->handle, sigint_event};
+ /* prepare list of handles */
+ nhandles = 0;
+ handles[nhandles++] = self->handle;
+ if (_PyOS_IsMainThread()) {
+ sigint_event = _PyOS_SigintEvent();
+ assert(sigint_event != NULL);
+ handles[nhandles++] = sigint_event;
+ }
- /* do the wait */
- Py_BEGIN_ALLOW_THREADS
+ /* do the wait */
+ Py_BEGIN_ALLOW_THREADS
+ if (sigint_event != NULL)
ResetEvent(sigint_event);
- res = WaitForMultipleObjects(2, handles, FALSE, msecs);
- Py_END_ALLOW_THREADS
-
- /* handle result */
- if (res != WAIT_OBJECT_0 + 1)
- break;
-
- /* got SIGINT so give signal handler a chance to run */
- Sleep(1);
-
- /* if this is main thread let KeyboardInterrupt be raised */
- if (PyErr_CheckSignals())
- return NULL;
-
- /* recalculate timeout */
- if (msecs != INFINITE) {
- ticks = GetTickCount();
- if ((DWORD)(ticks - start) >= full_msecs)
- Py_RETURN_FALSE;
- msecs = full_msecs - (ticks - start);
- }
- }
+ res = WaitForMultipleObjects(nhandles, handles, FALSE, full_msecs);
+ Py_END_ALLOW_THREADS
/* handle result */
switch (res) {
case WAIT_TIMEOUT:
Py_RETURN_FALSE;
- case WAIT_OBJECT_0:
+ case WAIT_OBJECT_0 + 0:
self->last_tid = GetCurrentThreadId();
++self->count;
Py_RETURN_TRUE;
+ case WAIT_OBJECT_0 + 1:
+ errno = EINTR;
+ return PyErr_SetFromErrno(PyExc_IOError);
case WAIT_FAILED:
return PyErr_SetFromWindowsErr(0);
default:
@@ -483,7 +472,7 @@ semlock_dealloc(SemLockObject* self)
static PyObject *
semlock_count(SemLockObject *self)
{
- return PyInt_FromLong((long)self->count);
+ return PyLong_FromLong((long)self->count);
}
static PyObject *
@@ -507,7 +496,7 @@ semlock_getvalue(SemLockObject *self)
the number of waiting threads */
if (sval < 0)
sval = 0;
- return PyInt_FromLong((long)sval);
+ return PyLong_FromLong((long)sval);
#endif
}