Re: is there something wrong with www.scsh.net?
[email protected] Fri, 6 Jul 2007 20:27:49 -0700
| Newsgroups | gmane.lisp.scheme.scsh |
|---|---|
| Message-ID | <[email protected]> |
On Sat 21 Apr 2007 16:39, Eric Knauel <[email protected]> writes: > scsh.net runs the SUnet web-server which sometimes gets into a stuck > state and refuses to work. There seems to be a bug somewhere in the > code that deals with executing CGI programs. However, we haven't > found this bug yet... It's not just CGI programs. I'm seeing the same thing for surflets in a personal application I'm running. The problem occurs when scsh spawns another scsh instance to do work. The parent listens on its end of the pipe, blocking for a response from the child: select(16, [15], [], [15], NULL) per strace. At the same time, the child process has called select in a way that is guaranteed to block: select(0, [], [], [], NULL) If the final parameter were a real struct timeval instead of NULL, then this would block for that time duration and return. But with a NULL struct timeval and empty fdset arguments, this just blocks forever (or until it gets some explicit interrupt, I suppose). Looking at the code, the only select() call that seems to allow this combination of parameters is in queue_ready_ports() in event.c. A combination of 'wait' being true, 'seconds' being -1, and 'pending' being empty would trigger it: if ((! wait) && (pending.first == NULL)) return (NO_ERRORS); FD_ZERO(&reads); FD_ZERO(&writes); FD_ZERO(&alls); limfd = 0; for (fdp = pending.first; fdp != NULL; fdp = fdp->next) { FD_SET(fdp->fd, fdp->is_input ? &reads : &writes); FD_SET(fdp->fd, &alls); if (limfd <= fdp->fd) limfd = fdp->fd + 1; } tvp = &tv; if (wait) if (seconds == -1){ tvp = NULL; } else { tv.tv_sec = seconds; tv.tv_usec = ticks * (1000000 / TICKS_PER_SECOND); } else timerclear(&tv); 'wait' is true so we skip the return (NO_ERRORS). 'pending.first' is NULL, so we don't hit any of the FD_SET calls. And 'seconds' is -1 so we set 'tvp' to NULL. Then this call /* time gap */ left = select(limfd, &reads, &writes, &alls, tvp); has 0, [], [], [] and NULL. Derek -- Derek Upham [email protected]