diff options
author | jhb <jhb@FreeBSD.org> | 2003-04-17 22:30:43 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2003-04-17 22:30:43 +0000 |
commit | 872336ea36fb488a069baa7c5b33f3221e51bd01 (patch) | |
tree | 5b0bd6a5212372ab1654f68de5879f6236aa39d2 /sys/kern/subr_prf.c | |
parent | a5725b28f3df458f3524cd1cf52febbd1c8fb2f3 (diff) | |
download | FreeBSD-src-872336ea36fb488a069baa7c5b33f3221e51bd01.zip FreeBSD-src-872336ea36fb488a069baa7c5b33f3221e51bd01.tar.gz |
Don't assume that p_session hasn't changed out from under us after unlocking
the process and session. Instead, cache a true reference to the session
when we do the hold and release our reference on that session. This avoids
the need for the proc lock when dropping the reference.
Diffstat (limited to 'sys/kern/subr_prf.c')
-rw-r--r-- | sys/kern/subr_prf.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 3efb7c2..7758b93 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -161,22 +161,23 @@ void tprintf(struct proc *p, int pri, const char *fmt, ...) { struct tty *tp = NULL; - int flags = 0, shld = 0; + int flags = 0; va_list ap; struct putchar_arg pca; int retval; + struct session *sess = NULL; if (pri != -1) flags |= TOLOG; if (p != NULL) { PROC_LOCK(p); if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { - SESS_LOCK(p->p_session); - SESSHOLD(p->p_session); - tp = p->p_session->s_ttyp; - SESS_UNLOCK(p->p_session); + sess = p->p_session; + SESS_LOCK(sess); PROC_UNLOCK(p); - shld++; + SESSHOLD(sess); + tp = sess->s_ttyp; + SESS_UNLOCK(sess); if (ttycheckoutq(tp, 0)) flags |= TOTTY; else @@ -190,12 +191,10 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) va_start(ap, fmt); retval = kvprintf(fmt, putchar, &pca, 10, ap); va_end(ap); - if (shld) { - PROC_LOCK(p); - SESS_LOCK(p->p_session); - SESSRELE(p->p_session); - SESS_UNLOCK(p->p_session); - PROC_UNLOCK(p); + if (sess != NULL) { + SESS_LOCK(sess); + SESSRELE(sess); + SESS_UNLOCK(sess); } msgbuftrigger = 1; } |