* signal.cc (nanosleep): Support 'infinite' sleep times.

(sleep): Avoid uninitialized memory.
This commit is contained in:
Eric Blake 2009-12-17 14:04:04 +00:00
parent 6681dfdc8c
commit 214f44da10
2 changed files with 55 additions and 19 deletions

View File

@ -1,3 +1,8 @@
2009-12-17 Eric Blake <ebb9@byu.net>
* signal.cc (nanosleep): Support 'infinite' sleep times.
(sleep): Avoid uninitialized memory.
2009-12-16 Thomas Wolff <towo@towo.net> 2009-12-16 Thomas Wolff <towo@towo.net>
* fhandler_console.cc (read): Detect and handle mouse wheel scrolling * fhandler_console.cc (read): Detect and handle mouse wheel scrolling

View File

@ -1,7 +1,7 @@
/* signal.cc /* signal.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008 Red Hat, Inc. 2005, 2006, 2007, 2008, 2009 Red Hat, Inc.
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
Significant changes by Sergey Okhapkin <sos@prospect.com.ru> Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
@ -87,20 +87,39 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
sig_dispatch_pending (); sig_dispatch_pending ();
pthread_testcancel (); pthread_testcancel ();
if ((unsigned int) rqtp->tv_sec > (HIRES_DELAY_MAX / 1000 - 1) if ((unsigned int) rqtp->tv_nsec > 999999999)
|| (unsigned int) rqtp->tv_nsec > 999999999)
{ {
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
} }
unsigned int sec = rqtp->tv_sec;
DWORD resolution = gtod.resolution (); DWORD resolution = gtod.resolution ();
DWORD req = ((rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000 bool done = false;
DWORD req;
DWORD rem;
while (!done)
{
/* Divide user's input into transactions no larger than 49.7
days at a time. */
if (sec > HIRES_DELAY_MAX)
{
req = ((HIRES_DELAY_MAX * 1000 + resolution - 1)
/ resolution * resolution);
sec -= HIRES_DELAY_MAX;
}
else
{
req = ((sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000
+ resolution - 1) / resolution) * resolution; + resolution - 1) / resolution) * resolution;
sec = 0;
done = true;
}
DWORD end_time = gtod.dmsecs () + req; DWORD end_time = gtod.dmsecs () + req;
syscall_printf ("nanosleep (%ld)", req); syscall_printf ("nanosleep (%ld)", req);
int rc = cancelable_wait (signal_arrived, req); int rc = cancelable_wait (signal_arrived, req);
DWORD rem;
if ((rem = end_time - gtod.dmsecs ()) > HIRES_DELAY_MAX) if ((rem = end_time - gtod.dmsecs ()) > HIRES_DELAY_MAX)
rem = 0; rem = 0;
if (rc == WAIT_OBJECT_0) if (rc == WAIT_OBJECT_0)
@ -108,12 +127,23 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
_my_tls.call_signal_handler (); _my_tls.call_signal_handler ();
set_errno (EINTR); set_errno (EINTR);
res = -1; res = -1;
break;
}
} }
if (rmtp) if (rmtp)
{ {
rmtp->tv_sec = rem / 1000; rmtp->tv_sec = sec + rem / 1000;
rmtp->tv_nsec = (rem % 1000) * 1000000; rmtp->tv_nsec = (rem % 1000) * 1000000;
if (sec)
{
rmtp->tv_nsec += rqtp->tv_nsec;
if (rmtp->tv_nsec >= 1000000000)
{
rmtp->tv_nsec -= 1000000000;
rmtp->tv_sec++;
}
}
} }
syscall_printf ("%d = nanosleep (%ld, %ld)", res, req, rem); syscall_printf ("%d = nanosleep (%ld, %ld)", res, req, rem);
@ -126,8 +156,9 @@ sleep (unsigned int seconds)
struct timespec req, rem; struct timespec req, rem;
req.tv_sec = seconds; req.tv_sec = seconds;
req.tv_nsec = 0; req.tv_nsec = 0;
nanosleep (&req, &rem); if (nanosleep (&req, &rem))
return rem.tv_sec + (rem.tv_nsec > 0); return rem.tv_sec + (rem.tv_nsec > 0);
return 0;
} }
extern "C" unsigned int extern "C" unsigned int
@ -136,7 +167,7 @@ usleep (useconds_t useconds)
struct timespec req; struct timespec req;
req.tv_sec = useconds / 1000000; req.tv_sec = useconds / 1000000;
req.tv_nsec = (useconds % 1000000) * 1000; req.tv_nsec = (useconds % 1000000) * 1000;
int res = nanosleep (&req, 0); int res = nanosleep (&req, NULL);
return res; return res;
} }