Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Nov 1998 08:44:03 -0500
From:      Bakul Shah <bakul@torrentnet.com>
To:        Terry Lambert <tlambert@primenet.com>
Cc:        nate@mt.sri.com (Nate Williams), hackers@FreeBSD.ORG
Subject:   Re: Supporting more than FD_SETSIZE fd's 
Message-ID:  <199811111344.IAA25228@chai.torrentnet.com>
In-Reply-To: Your message of "Wed, 11 Nov 1998 08:25:31 GMT." <199811110825.BAA06296@usr02.primenet.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
> > I need to support more than the default 255 FD's in an application (the
> > JDK for what it's worth).  To be portable, the code uses fd_set as
> > defined in <sys/types.h>.  Unfortunately, unless I redefine FD_SETSIZE
> > in every file that uses it, I still have a hard-limit on the number of
> > FD's the application can use.
> > 
> > Is there any 'portable' way of getting around this?

> Redefine FD_SETSIZE.
> 
> If you don't wwant to do it in every file that uses it, then either
> do it in the header file itself, or add -DFD_SETSIZE=1024 to CFLAGS.
> 
> 
> > I'd really like to
> > have it use whichever open FD that the limit allows, but I know now way
> > of having this happen?
> 
> I can't really parse this.  The "the limit allows" value is based on
> how many contiguous bits there are in an fd_set, which is based on
> the value of FD_SETSIZE at the time the fd_set is declared.

There is a way to select on all the file descriptors your
program can open.  The idea is to use getdtablesize() to find
the number of such descriptors and just allocate an array of
fd_mask.  Something like:

	int fd_setsize = getdtablesize();
	int fd_tablesize = howmany(max_fd_count, NFDBITS);
	fd_mask* readfds = calloc(fd_tablesize, sizeof(fd_mask));
	fd_mask* tmp_readfds = calloc(fd_tablesize, sizeof(fd_mask));

	...
	for (;;) {
	    memcpy(tmp_readfds, readfds, fd_tablesize*sizeof(fd_mask));
	    int nfds = select(maxfd_in_use+1, tmp_readfds, 0, 0, timeout);
	    if (nfds == -1) {
		if (errno == EINTR)
		    continue;
		perror("select");
		break;
	    }
	    if (nfds == 0) {
		/* handle timeout */
	    }
	    /* process ready input file descriptors */
	    for (int i = 0; i < nfds; i++) {
		if (!fd_isset(tmp_readfds, i))
		    continue;
		process_read(i);
	    }
	}
	...

You can `portably' define macros analogous to FD_SET, FD_CLR,
FD_ISSET, FD_COPY and FD_ZERO for this `flex' array type.

There is really no need to use FD_SETSIZE (unless you are
using functions that use select + fd_set and over which you
have no control).  Basically fd_set should have never been
defined.

The method I outlined above is portable in the sense that it
can be made to work on all machines that provide BSD style
select but getdtablesize() call may or may not exist on all
machines so you may have to fake it on such machines.  The
danger is, of course, if you are using X windows library or
some such other s/w that uses select and the simple minded
fd_set defined in sys/types.h.  In this case fds beyond
FD_SETSIZE may never get selected as they will never be
passed to select by such programs.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199811111344.IAA25228>