diff options
author | ed <ed@FreeBSD.org> | 2009-05-24 12:32:03 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-05-24 12:32:03 +0000 |
commit | cb56810df2e251e4b49d31f0b9c8ea1f1bad6f9b (patch) | |
tree | cff418388cf1ce21716b0c5d02ce12cd33ac5b5f /sys/kern/tty.c | |
parent | 56e5e587c8e87d5cb9fa566398a3676b36703171 (diff) | |
download | FreeBSD-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.c | 16 |
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); |