PR/43625: Mark Davies: Fix pselect(2) to honor the temporary mask. pselect(2)

(and pollts(2)) are similar to sigsuspend(2) in that they temporarily change
the process signal mask and wait for signal delivery. Factor out and share the
code that does this.
This commit is contained in:
christos 2011-05-18 03:51:41 +00:00
parent e2d6a49943
commit e2543d0362
3 changed files with 35 additions and 42 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_select.c,v 1.30 2011/03/06 04:41:58 rmind Exp $ */
/* $NetBSD: sys_select.c,v 1.31 2011/05/18 03:51:41 christos Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.30 2011/03/06 04:41:58 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.31 2011/05/18 03:51:41 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -219,10 +219,8 @@ sel_do_scan(const int op, void *fds, const int nf, const size_t ni,
struct timespec *ts, sigset_t *mask, register_t *retval)
{
lwp_t * const l = curlwp;
proc_t * const p = l->l_proc;
selcluster_t *sc;
kmutex_t *lock;
sigset_t oldmask;
struct timespec sleepts;
int error, timo;
@ -233,13 +231,7 @@ sel_do_scan(const int op, void *fds, const int nf, const size_t ni,
if (__predict_false(mask)) {
sigminusset(&sigcantmask, mask);
mutex_enter(p->p_lock);
oldmask = l->l_sigmask;
l->l_sigmask = *mask;
mutex_exit(p->p_lock);
} else {
/* XXXgcc */
oldmask = l->l_sigmask;
sigsuspendsetup(l, mask);
}
sc = curcpu()->ci_data.cpu_selcluster;
@ -314,12 +306,6 @@ state_check:
}
selclear();
if (__predict_false(mask)) {
mutex_enter(p->p_lock);
l->l_sigmask = oldmask;
mutex_exit(p->p_lock);
}
/* select and poll are not restarted after signals... */
if (error == ERESTART)
return EINTR;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_sig.c,v 1.32 2011/03/03 20:46:16 martin Exp $ */
/* $NetBSD: sys_sig.c,v 1.33 2011/05/18 03:51:41 christos Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.32 2011/03/03 20:46:16 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.33 2011/05/18 03:51:41 christos Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -604,14 +604,13 @@ sigpending1(struct lwp *l, sigset_t *ss)
mutex_exit(p->p_lock);
}
int
sigsuspend1(struct lwp *l, const sigset_t *ss)
void
sigsuspendsetup(struct lwp *l, const sigset_t *ss)
{
struct proc *p = l->l_proc;
if (ss) {
/*
* When returning from sigsuspend, we want
* When returning from sigsuspend/pselect/pollts, we want
* the old mask to be restored after the
* signal handler has finished. Thus, we
* save it here and mark the sigctx structure
@ -632,6 +631,13 @@ sigsuspend1(struct lwp *l, const sigset_t *ss)
mutex_exit(p->p_lock);
}
int
sigsuspend1(struct lwp *l, const sigset_t *ss)
{
if (ss)
sigsuspendsetup(l, ss);
while (kpause("pause", true, 0, NULL) == 0)
;

View File

@ -1,4 +1,4 @@
/* $NetBSD: signalvar.h,v 1.79 2011/04/27 00:38:37 rmind Exp $ */
/* $NetBSD: signalvar.h,v 1.80 2011/05/18 03:51:41 christos Exp $ */
/*
* Copyright (c) 1991, 1993
@ -148,6 +148,7 @@ int sigaction1(struct lwp *, int, const struct sigaction *,
struct sigaction *, const void *, int);
int sigprocmask1(struct lwp *, int, const sigset_t *, sigset_t *);
void sigpending1(struct lwp *, sigset_t *);
void sigsuspendsetup(struct lwp *, const sigset_t *);
int sigsuspend1(struct lwp *, const sigset_t *);
int sigaltstack1(struct lwp *, const struct sigaltstack *,
struct sigaltstack *);