Messages in this thread | | | Date | Wed, 28 Apr 1999 00:55:34 +0300 | From | Ville Herva <> | Subject | 2.0.3x: select returns dubious tv.tv_sec? |
| |
I had a problem with zsh, whose command line started working strangely after 248 days of uptime (jiffies > 2**31).
The problem turned out to be a select call that had invalid timeout value. The tv struct in zsh was first initialized to zero. Then select was called multiple times reinitializing the tv_usec part to zero before each call. tv_sec should have remained zero after select() as far as I can tell (and most like did before the 248 day barrier). From the man page:
"On Linux, timeout is modified to reflect the amount of time not slept; most other implementations do not do this."
So tv.tv_sec only get decremented during select().
The example program from the select man page with one additional printf:
vherva@turing:/home/vherva>cat u.c #include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h>
int main(void) { fd_set rfds; struct timeval tv; int retval;
/* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv); /* Don't rely on the value of tv now! */ printf("... because if one does, he'll get suprised: %i.\n", tv.tv_sec);
if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n");
exit(0); } vherva@turing:/home/vherva>gcc u.c -o u;./u q ... because if one does, he'll get suprised: 4. Data is available now. vherva@turing:/home/vherva>cd vherva@turing:/home/vherva>gcc u.c -o u;./u ... because if one does, he'll get suprised: 13124461. No data within five seconds. vherva@turing:/home/vherva>uptime 12:49am up 345 days, 4:48, 1 user, load average: 0.00, 0.00, 0.00
The problem is somewhere in the fs/select.c, I suspect.
if ((long) timeout < 0) timeout = 0; if (tvp && !(current->personality & STICKY_TIMEOUTS)) { put_user(timeout/HZ, &tvp->tv_sec); timeout %= HZ; timeout *= (1000000/HZ); put_user(timeout, &tvp->tv_usec); }
It seems clear that timeout (unsigned) is somewhere between 2**31 and 2**32 when those erranous values are returned. It is not clear to me how timeout gets those values.
-- v --
v@iki.fi
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |