diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-28 00:54:58 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-28 00:54:58 +0000 |
commit | f1647fb1cbff09e49a3d7feea79c20a197255cbe (patch) | |
tree | c6c82f4a4b7c0c9e271e3a05e8d5d345a6b03559 /lib/libc/gen | |
parent | d4ccefc30f9470b50ae2c5d80ed94ea52103a781 (diff) |
Eliminate race by stopping timer before restarting it with remaining time
(one more system call).
Diffstat (limited to 'lib/libc/gen')
-rw-r--r-- | lib/libc/gen/sleep.c | 32 | ||||
-rw-r--r-- | lib/libc/gen/usleep.c | 25 |
2 files changed, 44 insertions, 13 deletions
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c index b090c5959d7..cba9c97b2e1 100644 --- a/lib/libc/gen/sleep.c +++ b/lib/libc/gen/sleep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sleep.c,v 1.10 1995/05/03 12:52:43 mycroft Exp $ */ +/* $NetBSD: sleep.c,v 1.10.2.2 1995/10/26 22:05:50 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.10 1995/05/03 12:52:43 mycroft Exp $"; +static char rcsid[] = "$NetBSD: sleep.c,v 1.10.2.2 1995/10/26 22:05:50 pk Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -45,6 +45,8 @@ static char rcsid[] = "$NetBSD: sleep.c,v 1.10 1995/05/03 12:52:43 mycroft Exp $ #include <signal.h> #include <unistd.h> +static volatile int ringring; + unsigned int sleep(seconds) unsigned int seconds; @@ -99,12 +101,28 @@ sleep(seconds) set = oset; sigdelset(&set, SIGALRM); + ringring = 0; (void) sigsuspend(&set); - sigaction(SIGALRM, &oact, NULL); - sigprocmask(SIG_SETMASK, &oset, NULL); - - (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 { + struct itimerval nulltv; + /* + * Interrupted by other signal; allow for pending + * SIGALRM to be processed before resetting handler, + * after first turning off the timer. + */ + timerclear(&nulltv.it_interval); + timerclear(&nulltv.it_value); + (void) setitimer(ITIMER_REAL, &nulltv, &itv); + sigprocmask(SIG_SETMASK, &oset, NULL); + sigaction(SIGALRM, &oact, NULL); + (void) setitimer(ITIMER_REAL, &oitv, NULL); + } if (timerisset(&diff)) timeradd(&itv.it_value, &diff, &itv.it_value); @@ -115,5 +133,5 @@ sleep(seconds) static void sleephandler() { - + ringring = 1; } diff --git a/lib/libc/gen/usleep.c b/lib/libc/gen/usleep.c index 23b7279cff1..9067622b0ed 100644 --- a/lib/libc/gen/usleep.c +++ b/lib/libc/gen/usleep.c @@ -1,4 +1,4 @@ -/* $NetBSD: usleep.c,v 1.7 1995/05/03 12:52:44 mycroft Exp $ */ +/* $NetBSD: usleep.c,v 1.7.2.2 1995/10/26 22:05:52 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.7 1995/05/03 12:52:44 mycroft Exp $"; +static char rcsid[] = "$NetBSD: usleep.c,v 1.7.2.2 1995/10/26 22:05:52 pk Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -47,6 +47,8 @@ static char rcsid[] = "$NetBSD: usleep.c,v 1.7 1995/05/03 12:52:44 mycroft 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); - sigaction(SIGALRM, &oact, NULL); + if (!ringring) { + struct itimerval nulltv; + /* + * Interrupted by other signal; allow for pending + * SIGALRM to be processed before resetting handler, + * after first turning off the timer. + */ + timerclear(&nulltv.it_interval); + timerclear(&nulltv.it_value); + (void) setitimer(ITIMER_REAL, &nulltv, NULL); + } sigprocmask(SIG_SETMASK, &oset, NULL); - - (void) setitimer(ITIMER_REAL, &oitv, &itv); + sigaction(SIGALRM, &oact, NULL); + (void) setitimer(ITIMER_REAL, &oitv, NULL); } static void sleephandler() { - + ringring = 1; } |