bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lib/poll.c win32 deadlock


From: Erik Faye-Lund
Subject: lib/poll.c win32 deadlock
Date: Tue, 24 Aug 2010 22:58:57 +0200

Hi, after debugging the Win32-emulation of poll a bit more I think
I've found another problem with it. If all fds are pipes and have been
hanged up and the timeout is -1, poll() stalls infinitely at
MsgWaitForMultipleObjects(). That's because there's really nothing for
it to wait for, but MsgWaitForMultipleObjects() doesn't know that.

The following patch seems to fix it for me:

diff --git a/compat/win32/poll.c b/compat/win32/poll.c
index c537f28..4239d1d 100644
--- a/compat/win32/poll.c
+++ b/compat/win32/poll.c
@@ -437,7 +437,7 @@ poll (pfd, nfd, timeout)
   HANDLE h, handle_array[FD_SETSIZE + 2];
   DWORD ret, wait_timeout, nhandles;
   fd_set rfds, wfds, xfds;
-  BOOL poll_again;
+  BOOL poll_again, wait_msg = FALSE;
   MSG msg;
   int rc = 0;
   nfds_t i;
@@ -491,8 +491,8 @@ poll (pfd, nfd, timeout)
               FD_SET ((SOCKET) h, &xfds);
             }

-          if (requested)
-            WSAEventSelect ((SOCKET) h, hEvent, requested);
+          if (requested && !WSAEventSelect ((SOCKET) h, hEvent, requested))
+            wait_msg = TRUE;
         }
       else
         {
@@ -501,8 +501,12 @@ poll (pfd, nfd, timeout)
              a character is available.  win32_compute_revents eliminates
              bits for the "wrong" direction. */
           pfd[i].revents = win32_compute_revents (h, &sought);
-          if (sought)
+          if (sought) {
             handle_array[nhandles++] = h;
+
+            if (!(pfd[i].revents & POLLHUP))
+              wait_msg = TRUE;
+          }
           if (pfd[i].revents)
             wait_timeout = 0;
         }
@@ -524,7 +528,7 @@ poll (pfd, nfd, timeout)
         wait_timeout = timeout;
     }

-  for (;;)
+  for (;wait_msg;)
     {
       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
                                        wait_timeout, QS_ALLINPUT);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]