diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-21 20:26:56 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-21 20:26:56 (GMT) |
commit | 6dd381eb62278f75de7ba01626813de84cd248e7 (patch) | |
tree | 4b843b5767b3296212c5dbe8c696c1081b2fbfe0 /Modules/_multiprocessing/win32_functions.c | |
parent | ce4a9da70535b4bb9048147b141f01004af2133d (diff) | |
download | cpython-6dd381eb62278f75de7ba01626813de84cd248e7.zip cpython-6dd381eb62278f75de7ba01626813de84cd248e7.tar.gz cpython-6dd381eb62278f75de7ba01626813de84cd248e7.tar.bz2 |
Issue #12328: Under Windows, refactor handling of Ctrl-C events and
make _multiprocessing.win32.WaitForMultipleObjects interruptible when
the wait_flag parameter is false. Patch by sbt.
Diffstat (limited to 'Modules/_multiprocessing/win32_functions.c')
-rw-r--r-- | Modules/_multiprocessing/win32_functions.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/Modules/_multiprocessing/win32_functions.c b/Modules/_multiprocessing/win32_functions.c index c017b2a..ddc496d 100644 --- a/Modules/_multiprocessing/win32_functions.c +++ b/Modules/_multiprocessing/win32_functions.c @@ -679,6 +679,7 @@ win32_WaitForMultipleObjects(PyObject* self, PyObject* args) DWORD result; PyObject *handle_seq; HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + HANDLE sigint_event = NULL; Py_ssize_t nhandles, i; int wait_flag; int milliseconds = INFINITE; @@ -696,10 +697,10 @@ win32_WaitForMultipleObjects(PyObject* self, PyObject* args) nhandles = PySequence_Length(handle_seq); if (nhandles == -1) return NULL; - if (nhandles < 0 || nhandles >= MAXIMUM_WAIT_OBJECTS) { + if (nhandles < 0 || nhandles >= MAXIMUM_WAIT_OBJECTS - 1) { PyErr_Format(PyExc_ValueError, "need at most %zd handles, got a sequence of length %zd", - MAXIMUM_WAIT_OBJECTS, nhandles); + MAXIMUM_WAIT_OBJECTS - 1, nhandles); return NULL; } for (i = 0; i < nhandles; i++) { @@ -711,14 +712,27 @@ win32_WaitForMultipleObjects(PyObject* self, PyObject* args) return NULL; handles[i] = h; } + /* If this is the main thread then make the wait interruptible + by Ctrl-C unless we are waiting for *all* handles */ + if (!wait_flag && _PyOS_IsMainThread()) { + sigint_event = _PyOS_SigintEvent(); + assert(sigint_event != NULL); + handles[nhandles++] = sigint_event; + } Py_BEGIN_ALLOW_THREADS + if (sigint_event != NULL) + ResetEvent(sigint_event); result = WaitForMultipleObjects((DWORD) nhandles, handles, (BOOL) wait_flag, (DWORD) milliseconds); Py_END_ALLOW_THREADS if (result == WAIT_FAILED) return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); + else if (sigint_event != NULL && result == WAIT_OBJECT_0 + nhandles - 1) { + errno = EINTR; + return PyErr_SetFromErrno(PyExc_IOError); + } return PyLong_FromLong((int) result); } |