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:
parent
e2d6a49943
commit
e2543d0362
@ -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;
|
||||
|
@ -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,33 +604,39 @@ 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
|
||||
* the old mask to be restored after the
|
||||
* signal handler has finished. Thus, we
|
||||
* save it here and mark the sigctx structure
|
||||
* to indicate this.
|
||||
*/
|
||||
mutex_enter(p->p_lock);
|
||||
l->l_sigrestore = 1;
|
||||
l->l_sigoldmask = l->l_sigmask;
|
||||
l->l_sigmask = *ss;
|
||||
sigminusset(&sigcantmask, &l->l_sigmask);
|
||||
/*
|
||||
* 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
|
||||
* to indicate this.
|
||||
*/
|
||||
mutex_enter(p->p_lock);
|
||||
l->l_sigrestore = 1;
|
||||
l->l_sigoldmask = l->l_sigmask;
|
||||
l->l_sigmask = *ss;
|
||||
sigminusset(&sigcantmask, &l->l_sigmask);
|
||||
|
||||
/* Check for pending signals when sleeping. */
|
||||
if (sigispending(l, 0)) {
|
||||
lwp_lock(l);
|
||||
l->l_flag |= LW_PENDSIG;
|
||||
lwp_unlock(l);
|
||||
}
|
||||
mutex_exit(p->p_lock);
|
||||
/* Check for pending signals when sleeping. */
|
||||
if (sigispending(l, 0)) {
|
||||
lwp_lock(l);
|
||||
l->l_flag |= LW_PENDSIG;
|
||||
lwp_unlock(l);
|
||||
}
|
||||
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)
|
||||
;
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user