diff --git a/Modules/_multiprocessing/pipe_connection.c b/Modules/_multiprocessing/pipe_connection.c --- a/Modules/_multiprocessing/pipe_connection.c +++ b/Modules/_multiprocessing/pipe_connection.c @@ -92,9 +92,8 @@ static int conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save) { - DWORD bytes, deadline, delay; - int difference, res; - BOOL block = FALSE; + DWORD bytes, rslt; + HANDLE handles[2] = { NULL }; if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL)) return MP_STANDARD_ERROR; @@ -103,40 +102,30 @@ return bytes > 0; if (timeout < 0.0) - block = TRUE; + timeout = INFINITE; else - /* XXX does not check for overflow */ - deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5); + timeout *= 1000; /* timeout given in seconds, needs milliseconds */ - Sleep(0); + handles[0] = conn->handle; + handles[1] = sigint_event; - for (delay = 1 ; ; delay += 1) { - if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL)) - return MP_STANDARD_ERROR; - else if (bytes > 0) - return TRUE; + /* Note: The GIL was already yielded in our caller, connection_poll. + Return when either the pipe is ready or CTRL-C occurred. */ + rslt = WaitForMultipleObjects(2, handles, FALSE, timeout); - if (!block) { - difference = deadline - GetTickCount(); - if (difference < 0) - return FALSE; - if ((int)delay > difference) - delay = difference; - } - - if (delay > 20) - delay = 20; - - Sleep(delay); - - /* check for signals */ - Py_BLOCK_THREADS - res = PyErr_CheckSignals(); - Py_UNBLOCK_THREADS - - if (res) + switch (rslt) { + case WAIT_OBJECT_0: /* Pipe is ready. */ + if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL)) + return MP_STANDARD_ERROR; + else if (bytes > 0) + return TRUE; + break; + case WAIT_OBJECT_0 + 1: /* CTRL-C was signaled. */ return MP_EXCEPTION_HAS_BEEN_SET; + case WAIT_TIMEOUT: + return FALSE; } + return FALSE; } /*