Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Nov 1998 10:21:48 -0700
From:      Nate Williams <nate@mt.sri.com>
To:        Bakul Shah <bakul@torrentnet.com>
Cc:        Terry Lambert <tlambert@primenet.com>, nate@mt.sri.com (Nate Williams), hackers@FreeBSD.ORG
Subject:   Re: Supporting more than FD_SETSIZE fd's 
Message-ID:  <199811111721.KAA17285@mt.sri.com>
In-Reply-To: <199811111344.IAA25228@chai.torrentnet.com>
References:  <199811110825.BAA06296@usr02.primenet.com> <199811111344.IAA25228@chai.torrentnet.com>

next in thread | previous in thread | raw e-mail | index | archive | help
[
Increasing the number of file descriptors in a program instead of
having it hard-coded to FD_SETSIZE
]

> > > Is there any 'portable' way of getting around this?
> 
> > Redefine FD_SETSIZE.
> > 
> 
> 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);

Where is max_fd_count defined?

> 	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.

I tried doing this, but ended up with a core dump.  Unfortunately, I ran
out of time to work on it this week (real work calls), but I'll look
into doing this this weekend.  However, if someone has already done this
I'm more than willing to accept example code. :) :)


> 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.

For now, I'm mostly worried about all different versions of FreeBSD, so
my definition of 'portable' is limited.

> 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.

I understand....


Nate

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?199811111721.KAA17285>