Make sleep() and usleep() "eat" any stray SIGALRM signals during the

lifetime of the call, just like the old implementation did.  Previously,
we were only eating them if the application did not call sleep()/usleep()
with SIGALRM masked.

Submitted by:	ache
This commit is contained in:
Peter Wemm 1997-07-18 09:48:37 +00:00
parent ba68720f4f
commit 925d069aa8
2 changed files with 29 additions and 49 deletions

View File

@ -73,45 +73,35 @@ sleep(seconds)
struct timespec time_remaining;
struct sigaction act, oact;
sigset_t mask, omask;
int alarm_blocked;
if (seconds != 0) {
time_to_sleep.tv_sec = seconds;
time_to_sleep.tv_nsec = 0;
/* Block SIGALRM while fiddling with it */
/*
* Set up handler to interrupt signanosleep and ensure
* SIGARLM is not blocked. Block SIGALRM while fiddling
* with things.
*/
memset(&act, 0, sizeof(act));
act.sa_handler = sleephandler;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
sigprocmask(SIG_BLOCK, &mask, &omask);
/* Was SIGALRM blocked already? */
alarm_blocked = sigismember(&omask, SIGALRM);
if (!alarm_blocked) {
/*
* Set up handler to interrupt signanosleep only if
* SIGALRM was unblocked. (Save some syscalls)
*/
memset(&act, 0, sizeof(act));
act.sa_handler = sleephandler;
sigaction(SIGALRM, &act, &oact);
}
sigaction(SIGALRM, &act, &oact);
mask = omask;
sigdelset(&mask, SIGALRM);
/*
* signanosleep() uses the given mask for the lifetime of
* the syscall only - it resets on return. Note that the
* Old sleep explicitly unblocks SIGALRM during the sleep,
* we don't do that now since we don't depend on SIGALRM
* to end the timout. If the process blocks SIGALRM, it
* gets what it asks for.
* old sleep explicitly unblocks SIGALRM during the sleep.
*/
signanosleep(&time_to_sleep, &time_remaining, &omask);
signanosleep(&time_to_sleep, &time_remaining, &mask);
if (!alarm_blocked) {
/* Unwind */
sigaction(SIGALRM, &oact, (struct sigaction *)0);
sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
}
/* Unwind */
sigaction(SIGALRM, &oact, (struct sigaction *)0);
sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
/* return how long is left */
seconds = time_remaining.tv_sec;

View File

@ -74,37 +74,29 @@ usleep(useconds)
struct timespec time_remaining;
struct sigaction act, oact;
sigset_t mask, omask;
int alarm_blocked;
if (useconds != 0) {
time_to_sleep.tv_nsec = (useconds % 1000000) * 1000;
time_to_sleep.tv_sec = useconds / 1000000;
/* Block SIGALRM while fiddling with it */
/*
* Set up handler to interrupt signanosleep and ensure
* SIGARLM is not blocked. Block SIGALRM while fiddling
* with things.
*/
memset(&act, 0, sizeof(act));
act.sa_handler = sleephandler;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
sigprocmask(SIG_BLOCK, &mask, &omask);
/* Was SIGALRM blocked already? */
alarm_blocked = sigismember(&omask, SIGALRM);
if (!alarm_blocked) {
/*
* Set up handler to interrupt signanosleep only if
* SIGALRM was unblocked. (Save some syscalls)
*/
memset(&act, 0, sizeof(act));
act.sa_handler = sleephandler;
sigaction(SIGALRM, &act, &oact);
}
sigaction(SIGALRM, &act, &oact);
mask = omask;
sigdelset(&mask, SIGALRM);
/*
* signanosleep() uses the given mask for the lifetime of
* the syscall only - it resets on return. Note that the
* Old sleep explicitly unblocks SIGALRM during the sleep,
* we don't do that now since we don't depend on SIGALRM
* to end the timout. If the process blocks SIGALRM, it
* gets what it asks for.
* old sleep explicitly unblocks SIGALRM during the sleep.
*/
do {
@ -113,11 +105,9 @@ usleep(useconds)
} while (time_to_sleep.tv_sec != 0 &&
time_to_sleep.tv_nsec != 0);
if (!alarm_blocked) {
/* Unwind */
sigaction(SIGALRM, &oact, (struct sigaction *)0);
sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
}
/* Unwind */
sigaction(SIGALRM, &oact, (struct sigaction *)0);
sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
}
#endif /* _THREAD_SAFE */
}