Eliminate race in the "normal" case of not being interrupted by another signal.

This commit is contained in:
pk 1995-10-20 17:32:06 +00:00
parent 025a6b0e04
commit 0a3f02bda0
2 changed files with 40 additions and 14 deletions

View File

@ -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;
}

View File

@ -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;
}