Skip to content

Commit

Permalink
poll: honor the timeout on Win32
Browse files Browse the repository at this point in the history
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 <ethomson@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Edward Thomson authored and gitster committed Sep 14, 2015
1 parent 689efb7 commit ef8b53e
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions compat/poll/poll.c
Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit ef8b53e

Please sign in to comment.