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.) 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>
This commit is contained in:

committed by
Junio C Hamano

parent
689efb737a
commit
ef8b53e78c
@ -446,7 +446,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
|
|||||||
static HANDLE hEvent;
|
static HANDLE hEvent;
|
||||||
WSANETWORKEVENTS ev;
|
WSANETWORKEVENTS ev;
|
||||||
HANDLE h, handle_array[FD_SETSIZE + 2];
|
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;
|
fd_set rfds, wfds, xfds;
|
||||||
BOOL poll_again;
|
BOOL poll_again;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
@ -459,6 +459,12 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout != INFTIM)
|
||||||
|
{
|
||||||
|
orig_timeout = timeout;
|
||||||
|
start = GetTickCount();
|
||||||
|
}
|
||||||
|
|
||||||
if (!hEvent)
|
if (!hEvent)
|
||||||
hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
@ -603,7 +609,13 @@ restart:
|
|||||||
rc++;
|
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);
|
SleepEx (1, TRUE);
|
||||||
goto restart;
|
goto restart;
|
||||||
|
Reference in New Issue
Block a user