The attached patch prevents Cygwin from hanging in poll() (well really
select) when only invalid file descriptors are specified.  With the
patch applied, Cygwin's poll() now behaves the same as the one on Red
Hat 7.1 Linux.

The third attachment is a small test program that demonstrates the
problem.

For those interested in Python, this was the root cause to the test_poll
hang.

Thanks,
Jason
Index: poll.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/poll.cc,v
retrieving revision 1.17
diff -u -p -r1.17 poll.cc
--- poll.cc     2001/07/26 19:22:24     1.17
+++ poll.cc     2001/09/07 14:45:28
@@ -50,6 +50,7 @@ poll (struct pollfd *fds, unsigned int n
   memset (write_fds, 0, fds_size);
   memset (except_fds, 0, fds_size);
 
+  bool invalid_fds = false;
   for (unsigned int i = 0; i < nfds; ++i)
     if (!cygheap->fdtab.not_open (fds[i].fd))
       {
@@ -61,14 +62,21 @@ poll (struct pollfd *fds, unsigned int n
        if (fds[i].events & POLLPRI)
          FD_SET (fds[i].fd, except_fds);
       }
+      else
+       invalid_fds = true;
 
-  int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,
-                          timeout < 0 ? NULL : &tv);
+  int ret = 0;
+  if (!invalid_fds)
+    ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,
+                        timeout < 0 ? NULL : &tv);
 
   for (unsigned int i = 0; i < nfds; ++i)
     {
       if (!FD_ISSET (fds[i].fd, open_fds))
-       fds[i].revents = POLLNVAL;
+       {
+         fds[i].revents = POLLNVAL;
+         ret++;
+       }
       else if (cygheap->fdtab.not_open(fds[i].fd))
        fds[i].revents = POLLHUP;
       else if (ret < 0)
Fri Sep  7 10:53:34 2001  Jason Tishler <[EMAIL PROTECTED]>

        * poll.cc (poll): Change implementation to only call select() when no
        invalid file descriptors are specified.
#include <sys/poll.h>
#include <stdlib.h>
#include <errno.h>

int
main(int argc, char* argv[])
{
        struct pollfd fd;
        int s;

        fd.fd = atoi(argv[1]);
        fd.events = POLLIN;
        
        s = poll(&fd, 1, -1);
        if (s > 0)
        {
                printf("s = %d\n", s);
                printf("fd.revents = %x\n", fd.revents);
        }
        else if (s < 0)
                printf("failed with errno = %d\n", errno);

        return 0;
}

Reply via email to