diff options
| author | pk <pk@NetBSD.org> | 1995-10-20 17:32:06 +0000 |
|---|---|---|
| committer | pk <pk@NetBSD.org> | 1995-10-20 17:32:06 +0000 |
| commit | 0a3f02bda024e4d40ef1b62da1f9e9d51990bc9e (patch) | |
| tree | b7f0faa3e704663204beac7a390a9a49b73a84a5 | |
| parent | 025a6b0e047a5b993ae8b94624ed705eae75216f (diff) | |
Eliminate race in the "normal" case of not being interrupted by another signal.
| -rw-r--r-- | lib/libc/gen/sleep.c | 27 | ||||
| -rw-r--r-- | lib/libc/gen/usleep.c | 27 |
2 files changed, 40 insertions, 14 deletions
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c index 9d4563db990..78ed3f52603 100644 --- a/lib/libc/gen/sleep.c +++ b/lib/libc/gen/sleep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sleep.c,v 1.11 1995/10/16 18:58:47 pk Exp $ */ +/* $NetBSD: sleep.c,v 1.12 1995/10/20 17:32:06 pk Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: sleep.c,v 1.11 1995/10/16 18:58:47 pk Exp $"; +static char rcsid[] = "$NetBSD: sleep.c,v 1.12 1995/10/20 17:32:06 pk Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -45,6 +45,8 @@ static char rcsid[] = "$NetBSD: sleep.c,v 1.11 1995/10/16 18:58:47 pk Exp $"; #include <signal.h> #include <unistd.h> +static volatile int ringring; + unsigned int sleep(seconds) unsigned int seconds; @@ -99,21 +101,32 @@ sleep(seconds) set = oset; sigdelset(&set, SIGALRM); + ringring = 0; (void) sigsuspend(&set); - (void) setitimer(ITIMER_REAL, &oitv, &itv); + if (ringring) { + /* Our alarm went off; timer is not currently running */ + sigaction(SIGALRM, &oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + (void) setitimer(ITIMER_REAL, &oitv, &itv); + } else { + /* + * Interrupted by other signal; allow for pending + * SIGALRM to be processed before resetting handler. + */ + (void) setitimer(ITIMER_REAL, &oitv, &itv); + sigprocmask(SIG_SETMASK, &oset, NULL); + sigaction(SIGALRM, &oact, NULL); + } if (timerisset(&diff)) timeradd(&itv.it_value, &diff, &itv.it_value); - sigprocmask(SIG_SETMASK, &oset, NULL); - sigaction(SIGALRM, &oact, NULL); - return (itv.it_value.tv_sec); } static void sleephandler() { - + ringring = 1; } diff --git a/lib/libc/gen/usleep.c b/lib/libc/gen/usleep.c index 5df983c2c39..f3f65b7b589 100644 --- a/lib/libc/gen/usleep.c +++ b/lib/libc/gen/usleep.c @@ -1,4 +1,4 @@ -/* $NetBSD: usleep.c,v 1.8 1995/10/16 18:58:55 pk Exp $ */ +/* $NetBSD: usleep.c,v 1.9 1995/10/20 17:32:09 pk Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: usleep.c,v 1.8 1995/10/16 18:58:55 pk Exp $"; +static char rcsid[] = "$NetBSD: usleep.c,v 1.9 1995/10/20 17:32:09 pk Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -47,6 +47,8 @@ static char rcsid[] = "$NetBSD: usleep.c,v 1.8 1995/10/16 18:58:55 pk Exp $"; #define TICK 10000 /* system clock resolution in microseconds */ +static volatile int ringring; + void usleep(useconds) unsigned int useconds; @@ -93,16 +95,27 @@ usleep(useconds) set = oset; sigdelset(&set, SIGALRM); + ringring = 0; (void) sigsuspend(&set); - (void) setitimer(ITIMER_REAL, &oitv, &itv); - - sigprocmask(SIG_SETMASK, &oset, NULL); - sigaction(SIGALRM, &oact, NULL); + if (ringring) { + /* Our alarm went off; timer is not currently running */ + sigaction(SIGALRM, &oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + (void) setitimer(ITIMER_REAL, &oitv, &itv); + } else { + /* + * Interrupted by other signal; allow for pending + * SIGALRM to be processed before resetting handler. + */ + (void) setitimer(ITIMER_REAL, &oitv, &itv); + sigprocmask(SIG_SETMASK, &oset, NULL); + sigaction(SIGALRM, &oact, NULL); + } } static void sleephandler() { - + ringring = 1; } |
