public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* python select() is limited to fds < 64
@ 2011-03-22 19:50 Jon TURNEY
  2011-03-22 20:59 ` Václav Haisman
  0 siblings, 1 reply; 10+ messages in thread
From: Jon TURNEY @ 2011-03-22 19:50 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1286 bytes --]


python seems to be built with the default value of FD_SETSIZE, which is only
64 on cygwin.

I noticed this as it causes numerous tests in the twisted test suite to fail
with "ValueError: filedescriptor out of range in select()" exceptions, but can
also be demonstrated with a simple test case:

$ cat select_test.py

from socket import *
from select import select

ins = []

for i in range(1024):
    s = socket(AF_INET, SOCK_STREAM)
    ins.append(s)
    print "socket opened with fd", s.fileno()
    select(ins, [], [], 0)

$ python select_test.py
[...]
socket opened with fd 64
Traceback (most recent call last):
  File "./select_test.py", line 11, in <module>
    select(ins, [], [], 0)
ValueError: filedescriptor out of range in select()


Looking at the source [1], note that steps are already taken to increase the
default value of FD_SETSIZE on Win32, and I'd suggest it's appropriate to do
the same on cygwin, patch attached.

Note some code motion is necessary as FD_SETSIZE must be defined before
sys/types.h is included if we are going to override the default value set there.

I don't believe this can cause any ABI issues as the interface is in terms of
python lists, rather than fd_set values.

[1] http://hg.python.org/cpython/file/3c0edb157ea2/Modules/selectmodule.c


[-- Attachment #2: 2.6.5-FD_SETSIZE.patch --]
[-- Type: text/plain, Size: 1361 bytes --]

--- origsrc/Python-2.6.5/Modules/selectmodule.c	2009-10-27 15:39:53.000000000 +0000
+++ src/Python-2.6.5/Modules/selectmodule.c	2011-03-14 18:25:48.859375000 +0000
@@ -6,6 +6,21 @@
    >= 0.
 */
 
+/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
+   64 is too small (too many people have bumped into that limit).
+   Here we boost it.
+
+   Cygwin also defines FD_SETSIZE to 64, so also increase the limit on
+   Cygwin.  We must do this before sys/types.h is included, which otherwise
+   sets FD_SETSIZE to the default.
+
+   Users who want even more than the boosted limit should #define
+   FD_SETSIZE higher before this; e.g., via compiler /D switch.
+*/
+#if (defined(MS_WINDOWS) || defined(__CYGWIN__)) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 512
+#endif
+
 #include "Python.h"
 #include <structmember.h>
 
@@ -16,16 +31,6 @@
 #undef HAVE_BROKEN_POLL
 #endif
 
-/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
-   64 is too small (too many people have bumped into that limit).
-   Here we boost it.
-   Users who want even more than the boosted limit should #define
-   FD_SETSIZE higher before this; e.g., via compiler /D switch.
-*/
-#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
-#define FD_SETSIZE 512
-#endif 
-
 #if defined(HAVE_POLL_H)
 #include <poll.h>
 #elif defined(HAVE_SYS_POLL_H)



[-- Attachment #3: Type: text/plain, Size: 218 bytes --]

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread
* Re: python select() is limited to fds < 64
@ 2011-04-21  1:07 Bert Belder
  0 siblings, 0 replies; 10+ messages in thread
From: Bert Belder @ 2011-04-21  1:07 UTC (permalink / raw)
  To: cygwin

Christopher Faylor wrote:
> I forgot to add one bit of data.  Unless you go out of your way to
> change it, Cygwin's select can't wait for an fd > 63.  It's basically a
> bit mask.  So, there are two limitations: 1) the number of handles that
> you can wait for with WaitForMultipleObjects() and 2) the size of
> Cygwin's fd_set.

I have trouble believing this for two reasons:

1. I use node.js on Cygwin, and there seem to be no problems waiting for
readiness of a large (>1000) number of sockets. By default node uses poll()
which calls cygwin_select under the hood, but even when I force it to use
select() directly everything works ok.

2. Inspecting src/winsup/cygwin/select.cc, it looks like Cygwin distributes
the sockets (and other selectable stuff) that it is interested in over
different threads and uses WaitForMultipleObjects in those threads. Then in
the main thread it uses another WaiForMultipleObjects call to synchronize
between those threads. As different interests (read/write/error) and
different fd types require their own thread the fd limit must be somewhere
between a few hundred and  4032 (=64*63).

What did I miss?

Thanks,
Bert




--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-04-20 16:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-22 19:50 python select() is limited to fds < 64 Jon TURNEY
2011-03-22 20:59 ` Václav Haisman
2011-03-22 23:45   ` Christopher Faylor
2011-03-23 12:09     ` Jon TURNEY
2011-03-23 15:02       ` Christopher Faylor
2011-03-23 15:24         ` Eric Blake
2011-03-23 16:50         ` Jon TURNEY
2011-03-23 20:28           ` Christopher Faylor
2011-03-24 16:11             ` Jon TURNEY
2011-04-21  1:07 Bert Belder

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).