diff options
Diffstat (limited to 'Modules/_multiprocessing/semaphore.c')
-rw-r--r-- | Modules/_multiprocessing/semaphore.c | 59 |
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 } |