[PATCH] poll: honor the timeout on Win32
From: Johannes Schindelin <hidden>
Date: 2016-06-15 23:06:31
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Edward Thomson <redacted> Ensure that when passing a pipe, the gnulib poll replacement will not return 0 before the timeout has passed. Not obeying the timeout (and merely returning 0) causes pathological behavior when preparing a packfile for a repository and taking a long time to do so. If poll were to return 0 immediately, this would cause keep-alives to get sent as quickly as possible until the packfile was created. Such deviance from the standard would cause megabytes (or more) of keep-alive packets to be sent. GetTickCount is used as it is efficient, stable and monotonically increasing. (Neither GetSystemTime nor QueryPerformanceCounter have all three of these properties.) Signed-off-by: Edward Thomson <redacted> Signed-off-by: Johannes Schindelin <redacted> --- compat/poll/poll.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/compat/poll/poll.c b/compat/poll/poll.c
index a9b41d8..db4e03e 100644
--- a/compat/poll/poll.c
+++ b/compat/poll/poll.c@@ -446,7 +446,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) static HANDLE hEvent; WSANETWORKEVENTS ev; HANDLE h, handle_array[FD_SETSIZE + 2]; - DWORD ret, wait_timeout, nhandles; + DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0; fd_set rfds, wfds, xfds; BOOL poll_again; MSG msg;
@@ -459,6 +459,12 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) return -1; } + if (timeout != INFTIM) + { + orig_timeout = timeout; + start = GetTickCount(); + } + if (!hEvent) hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
@@ -603,7 +609,13 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) rc++; } - if (!rc && timeout == INFTIM) + if (!rc && orig_timeout && timeout != INFTIM) + { + elapsed = GetTickCount() - start; + timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed; + } + + if (!rc && timeout) { SleepEx (1, TRUE); goto restart; --
https://github.com/git/git/pull/176