aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-02-11 16:28:49 +0000
committerEd Schouten <ed@FreeBSD.org>2009-02-11 16:28:49 +0000
commitc0086bf20280407ccd3ed5a4ef984ce90f56b9ab (patch)
tree705a88f64ce1671f4a752f6c09d52d89e75c747b
parent54fffe2d67c0190cca8654a843a1d2f5c8141f50 (diff)
Notes
-rw-r--r--sys/kern/tty.c30
-rw-r--r--sys/sys/tty.h3
-rw-r--r--usr.sbin/pstat/pstat.85
-rw-r--r--usr.sbin/pstat/pstat.c5
4 files changed, 37 insertions, 6 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index d73683c196652..ee9595871d759 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -438,15 +438,28 @@ ttydev_write(struct cdev *dev, struct uio *uio, int ioflag)
if (tp->t_termios.c_lflag & TOSTOP) {
error = tty_wait_background(tp, curthread, SIGTTOU);
- if (error) {
- tty_unlock(tp);
- return (error);
- }
+ if (error)
+ goto done;
}
- error = ttydisc_write(tp, uio, ioflag);
- tty_unlock(tp);
+ if (ioflag & IO_NDELAY && tp->t_flags & TF_BUSY_OUT) {
+ /* Allow non-blocking writes to bypass serialization. */
+ error = ttydisc_write(tp, uio, ioflag);
+ } else {
+ /* Serialize write() calls. */
+ while (tp->t_flags & TF_BUSY_OUT) {
+ error = tty_wait(tp, &tp->t_bgwait);
+ if (error)
+ goto done;
+ }
+
+ tp->t_flags |= TF_BUSY_OUT;
+ error = ttydisc_write(tp, uio, ioflag);
+ tp->t_flags &= ~TF_BUSY_OUT;
+ cv_broadcast(&tp->t_bgwait);
+ }
+done: tty_unlock(tp);
return (error);
}
@@ -1880,6 +1893,11 @@ static struct {
{ TF_ZOMBIE, 'Z' },
{ TF_HOOK, 's' },
+ /* Keep these together -> 'bi' and 'bo'. */
+ { TF_BUSY, 'b' },
+ { TF_BUSY_IN, 'i' },
+ { TF_BUSY_OUT, 'o' },
+
{ 0, '\0'},
};
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index 218fd214cfd0f..893509395e443 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -83,6 +83,9 @@ struct tty {
#define TF_BYPASS 0x04000 /* Optimized input path. */
#define TF_ZOMBIE 0x08000 /* Modem disconnect received. */
#define TF_HOOK 0x10000 /* TTY has hook attached. */
+#define TF_BUSY_IN 0x20000 /* Process busy in read() -- not supported. */
+#define TF_BUSY_OUT 0x40000 /* Process busy in write(). */
+#define TF_BUSY (TF_BUSY_IN|TF_BUSY_OUT)
unsigned int t_revokecnt; /* (t) revoke() count. */
/* Buffering mechanisms. */
diff --git a/usr.sbin/pstat/pstat.8 b/usr.sbin/pstat/pstat.8
index b92abd8ae783d..5e3760cecb7ea 100644
--- a/usr.sbin/pstat/pstat.8
+++ b/usr.sbin/pstat/pstat.8
@@ -206,6 +206,11 @@ block mode input routine in use
connection lost
.It s
i/o being snooped
+.It b
+busy in
+.Xr read 2
+or
+.Xr write 2
.El
.Pp
The
diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c
index 2cb52fec88128..8272eee38bd65 100644
--- a/usr.sbin/pstat/pstat.c
+++ b/usr.sbin/pstat/pstat.c
@@ -315,6 +315,11 @@ static struct {
{ TF_ZOMBIE, 'Z' },
{ TF_HOOK, 's' },
+ /* Keep these together -> 'bi' and 'bo'. */
+ { TF_BUSY, 'b' },
+ { TF_BUSY_IN, 'i' },
+ { TF_BUSY_OUT, 'o' },
+
{ 0, '\0'},
};