mirror of
https://github.com/git/git.git
synced 2026-02-07 00:05:02 +00:00
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.)
This commit is contained in:
committed by
Johannes Schindelin
parent
710fe0c744
commit
ff9a20f2dd
@@ -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 @@ restart:
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user