Don't drop reference to tty in tty_close() if TS_ISOPEN is already cleared.

Reviewed by:	bde
This commit is contained in:
Tor Egge 2006-11-06 22:12:43 +00:00
parent 05b432d2d1
commit 40dee3da29

View File

@ -314,7 +314,7 @@ tty_open(struct cdev *device, struct tty *tp)
int int
tty_close(struct tty *tp) tty_close(struct tty *tp)
{ {
int s; int ostate, s;
funsetown(&tp->t_sigio); funsetown(&tp->t_sigio);
s = spltty(); s = spltty();
@ -331,17 +331,16 @@ tty_close(struct tty *tp)
tp->t_hotchar = 0; tp->t_hotchar = 0;
tp->t_pgrp = NULL; tp->t_pgrp = NULL;
tp->t_session = NULL; tp->t_session = NULL;
ostate = tp->t_state;
tp->t_state = 0; tp->t_state = 0;
knlist_clear(&tp->t_rsel.si_note, 0); knlist_clear(&tp->t_rsel.si_note, 0);
knlist_clear(&tp->t_wsel.si_note, 0); knlist_clear(&tp->t_wsel.si_note, 0);
/* /*
* Any close with tp->t_refcnt == 1 is wrong and is * Both final close and revocation close might end up calling
* an indication of a locking bug somewhere and that * this method. Only the thread clearing TS_ISOPEN should
* our open call has not been finished properly. * release the reference to the tty.
* Instead of putting an assert here we skip decrementing
* the refcount to work around any problems.
*/ */
if (tp->t_refcnt > 1) if (ISSET(ostate, TS_ISOPEN))
ttyrel(tp); ttyrel(tp);
splx(s); splx(s);
return (0); return (0);