zeromq / libzmq

ZeroMQ core engine in C++, implements ZMTP/3.1
https://www.zeromq.org
Mozilla Public License 2.0
9.75k stars 2.36k forks source link

FD_SETSIZE on Windows is at default 64 #57

Closed hintjens closed 13 years ago

hintjens commented 14 years ago

On Windows, winsock.h defines FD_SETSIZE to 64 if the application doesn't set it beforehand. See http://support.microsoft.com/kb/111855. The result is that any realistic application (e.g. a server) that handles more than a small fixed number of connections will die from socket exhaustion.

The actual limit on Windows is 32K (Windows NT) more or less (possibly some versions have artificially low limits). Xitami has used 1024 since 1996 or so.

The two ways of setting this are:

From experience, 1024 is a safe low value but the actual limit is presumably much higher.

Note that 0MQ invokes winsock.h in three places (windows.hpp, select.hpp, and zmq.h), and the value for this symbol has to be identical in all three places. It'd be better to have a single place where it's invoked.

mato commented 14 years ago

Note that I am the original reporter of this problem.

Caveat 1: FD_SETSIZE cannot be redefined in zmq.h at all, since that would export the definition to applications. Given that 0MQ may be used legitimately in conjunction with other socket code in an application we cannot assume that code is ready and willing to deal with any FD_SETSIZE value zmq.h might impose.

Caveat 2: It is unclear from Microsoft documentation what effect, if any, changing FD_SETSIZE in library code might have on an application using that library. Xitami is not a library, 0MQ is.

Therefore, after discussing with Martin Sustrik, this change cannot go into 2.0.x until we have a good solution for the two problems listed above, so I am removing the "maint" label from this issue.

What will go into 2.0.x is an assertion that will catch this problem rather than the current situation where sockets > FD_SETSIZE are silently ignored by zmq_poll() and zmq::select_t.

hintjens commented 14 years ago

The value of this constant affects source files and the structures they define when they call select(). This a library can define FD_SETSIZE itself before calling select(). Different sizes in different compiled programs is only relevant if they risk sharing the same sockets.

Note that zmq.h by including winsock.h already defines FS_SETSIZE to 64 unless it's overridden the application before zmq.h is included.

It's quite clear from the MS documentation that changing FD_SETSIZE in a library has NO impact on code using that library so long as the library hides its sockets. FD_SETSIZE is just used to construct the arrays passed to select().

mato commented 14 years ago

Irrespective of the issues with redefining FD_SETSIZE I just got a tip from Jon Dyte that the assertions added to zmq_poll() / poller_t (select.cpp) are not sufficient; given that on *NIX FD_SETs are implemented as a bit vector a second check should be done that we are not attempting to add a fd whose value is > FD_SETSIZE into a FD_SET. This is confirmed near the end of e.g. the Linux manpage for select().

Making a note of this here so that I don't forget about it; will make a patch over the next few days.

sustrik commented 13 years ago

Mato, what's the last comment above about? As for the original problem we've already agreed to set FD_SETSIZE to 1024 in zeromq solution for MSVC. This won't affect user's FD_SETSIZE value in any way.

sustrik commented 13 years ago

Fixed in both maint and master.