summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty.c
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-05-24 12:32:03 +0000
committered <ed@FreeBSD.org>2009-05-24 12:32:03 +0000
commitcb56810df2e251e4b49d31f0b9c8ea1f1bad6f9b (patch)
treecff418388cf1ce21716b0c5d02ce12cd33ac5b5f /sys/kern/tty.c
parent56e5e587c8e87d5cb9fa566398a3676b36703171 (diff)
downloadFreeBSD-src-cb56810df2e251e4b49d31f0b9c8ea1f1bad6f9b.zip
FreeBSD-src-cb56810df2e251e4b49d31f0b9c8ea1f1bad6f9b.tar.gz
Block when initially opening a TTY multiple times.
In the original MPSAFE TTY code, I changed the behaviour by returning EBUSY. I thought this made more sense, because it's basically a race to see who gets the TTY first. It turns out this is not a good change, because it also causes EBUSY to be returned when another process is closing the TTY. This can happen during startup, when /etc/rc (or one of its children) is still busy draining its data and /sbin/init is attempting to open the TTY to spawn a getty. Reported by: bz Tested by: bz
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r--sys/kern/tty.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 2468e88..804635e 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -206,6 +206,7 @@ ttydev_leave(struct tty *tp)
ttydevsw_close(tp);
tp->t_flags &= ~TF_OPENCLOSE;
+ cv_broadcast(&tp->t_dcdwait);
tty_rel_free(tp);
}
@@ -231,13 +232,17 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
tty_unlock(tp);
return (ENXIO);
}
+
/*
- * Prevent the TTY from being opened when being torn down or
- * built up by unrelated processes.
+ * Block when other processes are currently opening or closing
+ * the TTY.
*/
- if (tp->t_flags & TF_OPENCLOSE) {
- tty_unlock(tp);
- return (EBUSY);
+ while (tp->t_flags & TF_OPENCLOSE) {
+ error = tty_wait(tp, &tp->t_dcdwait);
+ if (error != 0) {
+ tty_unlock(tp);
+ return (error);
+ }
}
tp->t_flags |= TF_OPENCLOSE;
@@ -299,6 +304,7 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
tp->t_flags |= TF_OPENED_IN;
done: tp->t_flags &= ~TF_OPENCLOSE;
+ cv_broadcast(&tp->t_dcdwait);
ttydev_leave(tp);
return (error);
OpenPOWER on IntegriCloud