diff -r b6ca2d734f8e Lib/subprocess.py --- a/Lib/subprocess.py Wed Sep 14 23:54:09 2016 -0700 +++ b/Lib/subprocess.py Fri Sep 16 23:46:08 2016 +0000 @@ -1296,8 +1296,8 @@ else: timeout_millis = int(timeout * 1000) if self.returncode is None: - result = _winapi.WaitForSingleObject(self._handle, - timeout_millis) + result = _winapi.WaitForMultipleObjects( + [self._handle], False, timeout_millis) if result == _winapi.WAIT_TIMEOUT: raise TimeoutExpired(self.args, timeout) self.returncode = _winapi.GetExitCodeProcess(self._handle) diff -r b6ca2d734f8e Modules/_winapi.c --- a/Modules/_winapi.c Wed Sep 14 23:54:09 2016 -0700 +++ b/Modules/_winapi.c Fri Sep 16 23:46:08 2016 +0000 @@ -1322,6 +1322,7 @@ HANDLE handles[MAXIMUM_WAIT_OBJECTS]; HANDLE sigint_event = NULL; Py_ssize_t nhandles, i; + ULONGLONG deadline = GetTickCount64() + milliseconds; if (!PySequence_Check(handle_seq)) { PyErr_Format(PyExc_TypeError, @@ -1358,21 +1359,41 @@ handles[nhandles++] = sigint_event; } - Py_BEGIN_ALLOW_THREADS - if (sigint_event != NULL) - ResetEvent(sigint_event); - result = WaitForMultipleObjects((DWORD) nhandles, handles, - wait_flag, milliseconds); - Py_END_ALLOW_THREADS + do { + LONGLONG remaining; + + Py_BEGIN_ALLOW_THREADS + if (sigint_event) + ResetEvent(sigint_event); + result = WaitForMultipleObjects((DWORD)nhandles, handles, + wait_flag, milliseconds); + Py_END_ALLOW_THREADS + + if (!sigint_event || + result != WAIT_OBJECT_0 + nhandles - 1) + break; + + if (PyErr_CheckSignals()) + return NULL; + + if (milliseconds != INFINITE) { + remaining = deadline - GetTickCount64(); + + if (remaining < 0) { + if (nhandles > 1) /* wait 0 ms, without sigint_event */ + result = WaitForMultipleObjects((DWORD)(nhandles - 1), + handles, wait_flag, 0); + else /* Don't return an implicit WAIT_OBJECT_0 */ + result = WAIT_TIMEOUT; + break; + } + milliseconds = (DWORD)remaining; + } + } while (1); 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); + return PyLong_FromLong((int)result); } /*[clinic input]