From: Dave R. <da...@sy...> - 2002-09-29 01:00:17
|
> is does! > look at the sources (and docs): SOCKET-STATUS can return :ERROR for a > socket. Good grief! I missed that when I was reading the code. You're right. :input (in_sock) implies :error *pre-select()). My apologies. > CLISP always adds the socket so errorfds fd_set, i.e., CLISP always > checks for errors. > (sock . :error) would mean to wait _only_ for errors. > when is this useful? The way it's coded is perfectly adequate. > > - SOCKET-STATUS retries upon reception of EINTR. > > Time passage events are orthoginal, for the most part, but do > impact how we > > handle select() EINTRs. Time passage can be handled in one of > two ways: (1) > > polling, or (2) via signals. Either way, this impacts how we > handle EINTR > > in select(). My current C code uses polling. The last set of > gprof data I > > collected showed me in gettimeofday() 3% of the time! My > goal/desire would > > be to use an interval timer in the next version. > > I am not sure I understand this. > would you prefer CLISP to signal an error on EINTR? > C-c does interrupt SOCKET-STATUS already, right? Well, rather than dictate a solution (since there are several possibilities) let me state the problem: 1. select() for each socket until network traffix events occurs, i.e. :input, :output, :io, :error. 2. Every second execute a LISP function which handles time-based work. In a single-threaded environment like CLISP, network traffic and time events must be multiplexed in such a way that both needs are met (more or less efficiently). One approach (the one my C code uses) is to pass the time value (1 second) to select(). This ensures that we'll exit select() in time to meet our next time event. Unfortunately, with many users connected, we can exit select() many times per second. Which means we must call gettimeofday() every loop iteration to see how much longer before we should process our time events. We subtract the "next time period" from the current time and pass the difference to select(). This approach, although simple and seemingly elegant, is also pretty expensive. The second approach would be to use a 1 second interval timer. When the timer expires, the signal handler would increment a variable. At the next loop iteration we can use the variable to decide whether to handle time events (and how many). If we poll, EINTR handling isn't very important. In general, CLISP doesn't receive signals. Therefore, who really cares how we handle EINTR? However, in the second (interval timer) case, signals are important. We use signals to keep track of time. If socket-status re-select()s in the EINTR case, our time event processing may lag. So, the bottom line is, if we poll for time, re-select()ing isn't a big deal. But if we use setitimer() to handle time, EINTR becomes an issue. Make sense? Dave |