The READIN Family Album
Dogwood (May 20, 2003) (cf.)

READIN

Jeremy's journal

If there is a scheme,
perhaps this too is in the scheme,

Charles Reznikoff


(This is a page from my archives)
Front page
More recent posts
Older posts
More posts about:
Programming
Programming Projects
Projects

Archives index
Subscribe to RSS

This page renders best in Firefox (or Safari, or Chrome)

🦋 Multiplexing

The fix is in -- the server is using poll instead of select, a new version has been built and delivered to the client, it can handle loads of clients. Here is the long and short of how you do it (without error-checking, which is dull*):

The Old Code

void select_files(int *fds, int nfds)
{
    int i, maxid;
    fd_set rset, wset;
    timeval tval;

    FD_ZERO (&rset);
    FD_ZERO (&wset);
    maxid = 0;
    for (i = 0; i < nfds; ++i) {
        FD_SET (fds[i], &rset);
        FD_SET (fds[i], &wset);
        if (fds[i] > maxid) maxid = fds[i];
    }
    tval.tv_sec = 5;
    tval.tv_usec = 0;

    select (maxid + 1, &rset, &wset, NULL, &tval);
    for (i = 0; i < nfds; ++i) {
        if (FD_ISSET(fds[i], &rset)) 
            read_file(fds[i]);
        if (FD_ISSET(fds[i], &wset)) 
            write_file(fds[i]);
    }
}

The New Code

void poll_files(int *fds, int nfds)
{
    int i;
    pollfd *pfds = (pollfd *) 
              malloc (nfds * sizeof (pollfd));

    for (i = 0; i < nfds; ++i) {
        pfds[i].fd = fds[i];
        pfds[i].events = POLLIN | POLLOUT;
        pfds[i].revents = 0;
    }

    poll (pfds, nfds, 5000);
    for (i = 0; i < nfds; ++i) {
        if (pfds[i].revents & POLLIN) 
            read_file(fds[i]);
        if (pfds[i].revents & POLLOUT) 
            write_file(fds[i]);
    }
}

In order to take advantage of the newly accessible file descriptors above 1024, you will need to add these lines to your /etc/security/limits.conf file:

(username)          soft    nofile          1024
(username)          hard    nofile          4096

I chose 1024 for the soft limit since most apps are not interested in the high number of files, and 4096 for the hard limit because I read on some message boards that performance will degrade above that number. Feel free to choose other values.

You then need to make the following calls from your code (or call ulimit from the script that starts your application):

    struct rlimit nofile;

    if (getrlimit (RLIMIT_NOFILE, &nofile) != 0) {
        fprintf (stderr, "Could not get NOFILE");
        exit (1);
    }
    nofile.rlim_cur = 4096;
    if (setrlimit (RLIMIT_NOFILE, &nofile) != 0) {
        fprintf (stderr, "Could not set NOFILE");
        exit (1);
    }

*If you're interested in the error-checking code, drop me a line -- I just don't feel like typing it out right now.

posted afternoon of Friday, February 15th, 2008
➳ More posts about Programming
➳ More posts about Programming Projects
➳ More posts about Projects

Respond:

Name:
E-mail:
(will not be displayed)
Link:
Remember info

Drop me a line! or, sign my Guestbook.
    •
Check out Ellen's writing at Patch.com.

What's of interest:

(Other links of interest at my Google+ page. It's recommended!)

Where to go from here...

Friends and Family
Programming
Texts
Music
Woodworking
Comix
Blogs
South Orange
readinsinglepost