summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpk <pk@NetBSD.org>1995-10-20 17:32:06 +0000
committerpk <pk@NetBSD.org>1995-10-20 17:32:06 +0000
commit0a3f02bda024e4d40ef1b62da1f9e9d51990bc9e (patch)
treeb7f0faa3e704663204beac7a390a9a49b73a84a5
parent025a6b0e047a5b993ae8b94624ed705eae75216f (diff)
Eliminate race in the "normal" case of not being interrupted by another signal.
-rw-r--r--lib/libc/gen/sleep.c27
-rw-r--r--lib/libc/gen/usleep.c27
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;
}