summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/condvar.c
diff options
context:
space:
mode:
authorcwb <none@none>2005-07-21 08:29:59 -0700
committercwb <none@none>2005-07-21 08:29:59 -0700
commit16ade92d9ce9c9ab33a25f7a2fdd00b581b6efda (patch)
tree1a878f0ece76b0bbe0842cc9d25e5ca6eb8e4997 /usr/src/uts/common/os/condvar.c
parent80b8e1d8e1181e1da4f3eccd1df6261d543bf793 (diff)
downloadillumos-joyent-16ade92d9ce9c9ab33a25f7a2fdd00b581b6efda.tar.gz
4522909 automountd hangs with executable maps
Diffstat (limited to 'usr/src/uts/common/os/condvar.c')
-rw-r--r--usr/src/uts/common/os/condvar.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/usr/src/uts/common/os/condvar.c b/usr/src/uts/common/os/condvar.c
index 8e8c189d57..21b91391f6 100644
--- a/usr/src/uts/common/os/condvar.c
+++ b/usr/src/uts/common/os/condvar.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -555,45 +555,49 @@ cv_wait_stop(kcondvar_t *cvp, kmutex_t *mp, int wakeup_time)
(void) untimeout(id);
/*
- * Check for reasons to stop, if lwp_nostop is not true.
+ * Check for reasons to stop, and stop if lwp_nostop is zero.
* See issig_forreal() for explanations of the various stops.
+ * Like issig_forreal(), we allow a PR_SUSPENDED/SUSPEND_NORMAL
+ * to occur even if lwp_nostop is set.
*/
mutex_enter(&p->p_lock);
- while (lwp->lwp_nostop == 0 && !(p->p_flag & SEXITLWPS)) {
+ while (!(p->p_flag & SEXITLWPS)) {
/*
* Hold the lwp here for watchpoint manipulation.
*/
- if (t->t_proc_flag & TP_PAUSE) {
+ if ((t->t_proc_flag & TP_PAUSE) && !lwp->lwp_nostop) {
stop(PR_SUSPENDED, SUSPEND_PAUSE);
continue;
}
/*
* System checkpoint.
*/
- if (t->t_proc_flag & TP_CHKPT) {
+ if ((t->t_proc_flag & TP_CHKPT) && !lwp->lwp_nostop) {
stop(PR_CHECKPOINT, 0);
continue;
}
/*
* Honor fork1(), watchpoint activity (remapping a page),
- * and lwp_suspend() requests.
+ * and lwp_suspend() regardless of whether lwp_nostop is
+ * set but not if lwp_nostop_r is set (to avoid a recursive
+ * call to prstop()).
*/
- if ((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) ||
- (t->t_proc_flag & TP_HOLDLWP)) {
+ if (((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) ||
+ (t->t_proc_flag & TP_HOLDLWP)) && !lwp->lwp_nostop_r) {
stop(PR_SUSPENDED, SUSPEND_NORMAL);
continue;
}
/*
* Honor /proc requested stop.
*/
- if (t->t_proc_flag & TP_PRSTOP) {
+ if ((t->t_proc_flag & TP_PRSTOP) && !lwp->lwp_nostop) {
stop(PR_REQUESTED, 0);
}
/*
* If some lwp in the process has already stopped
* showing PR_JOBCONTROL, stop in sympathy with it.
*/
- if (p->p_stopsig && t != p->p_agenttp) {
+ if (p->p_stopsig && !lwp->lwp_nostop && (t != p->p_agenttp)) {
stop(PR_JOBCONTROL, p->p_stopsig);
continue;
}