git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] poll: honor the timeout on Win32

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Sep 12, 2015, 17:50 UTC
Message-ID
<0000014fc2adfd6a-40802cb4-acb3-4b45-ac12-ce046f6c408b-000000@eu-west-1.amazonses.com>
From: Edward Thomson <ethomson@microsoft.com>

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>
---
 compat/poll/poll.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/compat/poll/poll.c b/compat/poll/poll.c
index a9b41d8..db4e03e 100644
--- a/compat/poll/poll.c
+++ b/compat/poll/poll.c
@@ -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 @@ 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;

--
https://github.com/git/git/pull/176
Message 1 of 1 in “poll: honor the timeout on Win32”
  1. poll: honor the timeout on Win32Johannes Schindelin, Sep 12, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.