kern/147647: select wakes after 24 hours even if timeout is longer
Martin Simmons
martin at lispworks.com
Mon Jun 7 12:10:08 UTC 2010
>Number: 147647
>Category: kern
>Synopsis: select wakes after 24 hours even if timeout is longer
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Jun 07 12:10:03 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator: Martin Simmons
>Release: 8.0-RELEASE-p2
>Organization:
>Environment:
FreeBSD lwfs1-cam.cam.lispworks.com 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #0: Tue Jan 5 21:11:58 UTC 2010 root at amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
The select system call wakes indicating timeout after 24 hours even if the timeout specifies a longer delay.
>How-To-Repeat:
Running the code below with argument 10000000 exits after 24 hours with:
res = 0 delay = 86398 fd = 3, fd active = 0
#include <sys/select.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
fd_set fdset;
struct timeval tv;
int fds[2], fd, res;
time_t start, end;
pipe(fds);
fd = fds[0];
tv.tv_sec = atoi(argv[1]);
tv.tv_usec = 0;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
start = time(NULL);
res = select(fd + 1, &fdset, NULL, NULL, &tv);
end = time(NULL);
printf("res = %d delay = %ld fd = %d, fd active = %d\n",
res, (long)(end - start), fd, FD_ISSET(fd, &fdset));
return 0;
}
>Fix:
I think the problem is that seltdwait is implemented using cv_timedwait_sig, which returns EWOULDBLOCK on timeout. The calls to seltdwait in kern_select etc limit the timeout to a maximum of 24 * 60 * 60 * hz but interpret EWOULDBLOCK as a reason to exit rather than checking the actual timeout.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list