diff options
author | tegge <tegge@FreeBSD.org> | 2006-11-06 22:12:43 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2006-11-06 22:12:43 +0000 |
commit | 4fdb31ed2488b67fda65dab50b3b9b0c49c2d915 (patch) | |
tree | ad5278e0a08f398e1c9e692865c68f9e11d48cc4 /sys/kern/tty.c | |
parent | 367bc6b8e0ccf1af12ccdfff7d83ef3ec5f6be9a (diff) | |
download | FreeBSD-src-4fdb31ed2488b67fda65dab50b3b9b0c49c2d915.zip FreeBSD-src-4fdb31ed2488b67fda65dab50b3b9b0c49c2d915.tar.gz |
Don't drop reference to tty in tty_close() if TS_ISOPEN is already cleared.
Reviewed by: bde
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r-- | sys/kern/tty.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 17205f2..bd7cf8d 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -314,7 +314,7 @@ tty_open(struct cdev *device, struct tty *tp) int tty_close(struct tty *tp) { - int s; + int ostate, s; funsetown(&tp->t_sigio); s = spltty(); @@ -331,17 +331,16 @@ tty_close(struct tty *tp) tp->t_hotchar = 0; tp->t_pgrp = NULL; tp->t_session = NULL; + ostate = tp->t_state; tp->t_state = 0; knlist_clear(&tp->t_rsel.si_note, 0); knlist_clear(&tp->t_wsel.si_note, 0); /* - * Any close with tp->t_refcnt == 1 is wrong and is - * an indication of a locking bug somewhere and that - * our open call has not been finished properly. - * Instead of putting an assert here we skip decrementing - * the refcount to work around any problems. + * Both final close and revocation close might end up calling + * this method. Only the thread clearing TS_ISOPEN should + * release the reference to the tty. */ - if (tp->t_refcnt > 1) + if (ISSET(ostate, TS_ISOPEN)) ttyrel(tp); splx(s); return (0); |