Make do_block use poll() rather than select()

Mike Hearn mike at theoretic.com
Fri Aug 8 11:05:22 CDT 2003


ChangeLog:
Prevent the winsock code doing some stack trashing when there are
>FD_SET_SIZE (1024) file descriptors open at once.

 
-------------- next part --------------
[mike at littlegreen working]$ cvs diff dlls/winsock/socket.c
Index: dlls/winsock/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/winsock/socket.c,v
retrieving revision 1.130
diff -u -r1.130 socket.c
--- dlls/winsock/socket.c       30 Jun 2003 20:53:48 -0000      1.130
+++ dlls/winsock/socket.c       8 Aug 2003 13:10:32 -0000
@@ -103,6 +103,11 @@
 # define HAVE_IPX
 #endif
  
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
+
+
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
@@ -632,24 +637,38 @@
     }
 }
  
+/* utility: given an fd, will block until one of the events specified in mask occur
+   possible masks are:
+     001b => read
+     010b => write
+     100b => exception
+*/
 static int do_block( int fd, int mask )
 {
-    fd_set fds[3];
-    int i, r;
+  short events = 0;
+  int r = 0;
+  struct pollfd pfd;
+
+  if (mask & (1<<0))
+    events |= POLLIN;
+  if (mask & (1<<1))
+    events |= POLLOUT;
+  if (mask & (1<<2))
+    events |= POLLERR;
+
+  pfd.fd = fd;
+  pfd.events = events;
+  poll(&pfd, 1, -1);
+
+  if (pfd.revents & POLLIN)
+    r |= (1<<1);
+  if (pfd.revents & POLLOUT)
+    r |= (1<<2);
+  if (pfd.revents & POLLERR)
+    r |= (1<<3);
+
+  return r;
  
-    FD_ZERO(&fds[0]);
-    FD_ZERO(&fds[1]);
-    FD_ZERO(&fds[2]);
-    for (i=0; i<3; i++)
-       if (mask & (1<<i))
-           FD_SET(fd, &fds[i]);
-    i = select( fd+1, &fds[0], &fds[1], &fds[2], NULL );
-    if (i <= 0) return -1;
-    r = 0;
-    for (i=0; i<3; i++)
-       if (FD_ISSET(fd, &fds[i]))
-           r |= 1<<i;
-    return r;
 }
  
 void* __ws_memalloc( int size )


More information about the wine-patches mailing list