{"thread":{"id":"40340","subject":"[PATCH] poll: honor the timeout on Win32","startedAt":"2015-09-12T17:50:26Z","lastAt":"2015-09-12T17:50:26Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"269831","messageId":"0000014fc2adfd6a-40802cb4-acb3-4b45-ac12-ce046f6c408b-000000@eu-west-1.amazonses.com","threadId":"40340","inReplyTo":null,"subject":"[PATCH] poll: honor the timeout on Win32","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2015-09-12T17:50:26Z","receivedAt":"2015-09-12T17:50:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Edward Thomson <ethomson@microsoft.com>\n\nEnsure that when passing a pipe, the gnulib poll replacement will not\nreturn 0 before the timeout has passed.\n\nNot obeying the timeout (and merely returning 0) causes pathological\nbehavior when preparing a packfile for a repository and taking a\nlong time to do so.  If poll were to return 0 immediately, this would\ncause keep-alives to get sent as quickly as possible until the packfile\nwas created.  Such deviance from the standard would cause megabytes (or\nmore) of keep-alive packets to be sent.\n\nGetTickCount is used as it is efficient, stable and monotonically\nincreasing.  (Neither GetSystemTime nor QueryPerformanceCounter have\nall three of these properties.)\n\nSigned-off-by: Edward Thomson <ethomson@microsoft.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/poll/poll.c | 16 ++++++++++++++--\n 1 file changed, 14 insertions(+), 2 deletions(-)\n\ndiff --git a/compat/poll/poll.c b/compat/poll/poll.c\nindex a9b41d8..db4e03e 100644\n--- a/compat/poll/poll.c\n+++ b/compat/poll/poll.c\n@@ -446,7 +446,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)\n   static HANDLE hEvent;\n   WSANETWORKEVENTS ev;\n   HANDLE h, handle_array[FD_SETSIZE + 2];\n-  DWORD ret, wait_timeout, nhandles;\n+  DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0;\n   fd_set rfds, wfds, xfds;\n   BOOL poll_again;\n   MSG msg;\n@@ -459,6 +459,12 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)\n       return -1;\n     }\n \n+  if (timeout != INFTIM)\n+    {\n+      orig_timeout = timeout;\n+      start = GetTickCount();\n+    }\n+\n   if (!hEvent)\n     hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);\n \n@@ -603,7 +609,13 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)\n \trc++;\n     }\n \n-  if (!rc && timeout == INFTIM)\n+  if (!rc && orig_timeout && timeout != INFTIM)\n+    {\n+      elapsed = GetTickCount() - start;\n+      timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed;\n+    }\n+\n+  if (!rc && timeout)\n     {\n       SleepEx (1, TRUE);\n       goto restart;\n\n--\nhttps://github.com/git/git/pull/176\n"}]}