Skip to content

Commit 09b6a77

Browse files
Edward Thomsondscho
authored andcommitted
poll: honor the timeout on Win32
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.)
1 parent b578abd commit 09b6a77

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

compat/poll/poll.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
446446
static HANDLE hEvent;
447447
WSANETWORKEVENTS ev;
448448
HANDLE h, handle_array[FD_SETSIZE + 2];
449-
DWORD ret, wait_timeout, nhandles;
449+
DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0;
450450
fd_set rfds, wfds, xfds;
451451
BOOL poll_again;
452452
MSG msg;
@@ -459,6 +459,12 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
459459
return -1;
460460
}
461461

462+
if (timeout != INFTIM)
463+
{
464+
orig_timeout = timeout;
465+
start = GetTickCount();
466+
}
467+
462468
if (!hEvent)
463469
hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
464470

@@ -603,7 +609,13 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
603609
rc++;
604610
}
605611

606-
if (!rc && timeout == INFTIM)
612+
if (!rc && orig_timeout && timeout != INFTIM)
613+
{
614+
elapsed = GetTickCount() - start;
615+
timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed;
616+
}
617+
618+
if (!rc && timeout)
607619
{
608620
SleepEx (1, TRUE);
609621
goto restart;

0 commit comments

Comments
 (0)