From: BG - Ben Armstrong Date: 2005-05-27T22:49:50+09:00 Subject: Re: select() on non-sockets in eval.c Nobu, if I understand this code correctly, I think I see a problem: On Wednesday, May 25, 2005 6:25 AM, nobuyoshi nakada wrote: > + /* count socket and non-socket fds */ ... > + if (is_socket(i)) { > + if (r) FD_SET(i, (rp = &rs)); > + if (w) FD_SET(i, (wp = &ws)); > + if (e) FD_SET(i, (ep = &es)); > + maxsock = i + 1; > + socks++; > + } So we now have socket fds in rp, wp & ep. Later, once we have ruled out the socket-only & non-socket-only cases which are trivial, we go on to just select against the socket fds: > + ret = select(maxsock, rp, wp, ep, &z); If an error was returned, we just ignore it and return nsocks, the # of non-socket fds, and return the non-socket fd bits in rfd, wfd & efd. So far, so good. But if select returned >= 0, then for each set bit in rp, wp & ep, we set a bit in rfd, wfd & efd to return: > + for (i = 0; i < maxsock; ++i) { > + if (rp && FD_ISSET(i, rp)) { > + FD_SET(i, rfd); > + ret++; > + } ... etc. ... This is where I get confused about what you intended. Ret started as the return value from select on the sockets, and rp, wp and ep should already contain the ready socket fds. Why are we adding into ret the count of *socket* fds ready? Shouldn't this be setting rfd, wfd and efd to the returned rp, wp and ep, and then add in the *non-socket* bits (and increment ret per ready non-socket fd)? But we don't have any variables storing just the non-socket bits, so we can't do that. Supposing ret were zero after performing the select() on the socket fds, as I am seeing in my tests. Then rp, wp and ep will all have no bits set, so ret isn't incremented any further. The combined socket+nonsocket ret is 0, whereas it should have been a count of all non-socket fds (which are assumed to be ready). My debug print statements confirm this. So to fix this, we want to keep track of the non-socket fds from rfd, wfd & efd (before we called select()) and then add back in those bits (and count them in ret) after we get a non-negative result from the real select(). I'm going to compare this again with what is done in win32.c just to make sure before proceeding. Thanks, Ben