This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

poll() patch


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 <jason@tishler.net>

	* 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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]