summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2010-08-11 07:34:44 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2010-08-11 07:34:44 +0000
commit0a79760010cafa3e25fd950c0c3d22f8cc649567 (patch)
treeb2104529643980f8fc2f817fb5c896365c61f1c8
parent1ab3a17cfaaf8e25698adc00e49d111278f44e17 (diff)
Change the way backoff works. Instead of stopping reading from the pty
when the client tty backs up too much, just stop updating the tty and only update the internal screen. Then when the tty recovers, force a redraw. This prevents a dodgy client from causing other clients to go into backoff while still allowing tmux to be responsive (locally) when seeing lots of output.
-rw-r--r--usr.bin/tmux/server-client.c50
-rw-r--r--usr.bin/tmux/server-window.c38
-rw-r--r--usr.bin/tmux/tmux.h9
-rw-r--r--usr.bin/tmux/tty.c6
4 files changed, 60 insertions, 43 deletions
diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c
index 72cf9a1239a..3bc813ce45f 100644
--- a/usr.bin/tmux/server-client.c
+++ b/usr.bin/tmux/server-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.37 2010/07/28 22:15:15 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.38 2010/08/11 07:34:43 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -492,6 +492,50 @@ server_client_check_exit(struct client *c)
c->flags &= ~CLIENT_EXIT;
}
+/*
+ * Check if the client should backoff. During backoff, data from external
+ * programs is not written to the terminal. When the existing data drains, the
+ * client is redrawn.
+ *
+ * There are two backoff phases - both the tty and client have backoff flags -
+ * the first to allow existing data to drain and the latter to ensure backoff
+ * is disabled until the redraw has finished and prevent the redraw triggering
+ * another backoff.
+ */
+void
+server_client_check_backoff(struct client *c)
+{
+ struct tty *tty = &c->tty;
+ size_t used;
+
+ used = EVBUFFER_LENGTH(tty->event->output);
+
+ /*
+ * If in the second backoff phase (redrawing), don't check backoff
+ * until the redraw has completed (or enough of it to drop below the
+ * backoff threshold).
+ */
+ if (c->flags & CLIENT_BACKOFF) {
+ if (used > BACKOFF_THRESHOLD)
+ return;
+ c->flags &= ~CLIENT_BACKOFF;
+ return;
+ }
+
+ /* Once drained, allow data through again and schedule redraw. */
+ if (tty->flags & TTY_BACKOFF) {
+ if (used != 0)
+ return;
+ tty->flags &= ~TTY_BACKOFF;
+ c->flags |= (CLIENT_BACKOFF|CLIENT_REDRAWWINDOW|CLIENT_STATUS);
+ return;
+ }
+
+ /* If too much data, start backoff. */
+ if (used > BACKOFF_THRESHOLD)
+ tty->flags |= TTY_BACKOFF;
+}
+
/* Check for client redraws. */
void
server_client_check_redraw(struct client *c)
@@ -520,6 +564,10 @@ server_client_check_redraw(struct client *c)
if (c->flags & CLIENT_REDRAW) {
screen_redraw_screen(c, 0, 0);
c->flags &= ~(CLIENT_STATUS|CLIENT_BORDERS);
+ } else if (c->flags & CLIENT_REDRAWWINDOW) {
+ TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry)
+ screen_redraw_pane(c, wp);
+ c->flags &= ~CLIENT_REDRAWWINDOW;
} else {
TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
if (wp->flags & PANE_REDRAW)
diff --git a/usr.bin/tmux/server-window.c b/usr.bin/tmux/server-window.c
index c2a00c4c46c..e6f9b35b2e6 100644
--- a/usr.bin/tmux/server-window.c
+++ b/usr.bin/tmux/server-window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-window.c,v 1.16 2010/07/19 21:13:03 nicm Exp $ */
+/* $OpenBSD: server-window.c,v 1.17 2010/08/11 07:34:43 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,31 +29,6 @@ int server_window_check_activity(struct session *, struct winlink *);
int server_window_check_content(
struct session *, struct winlink *, struct window_pane *);
-/* Check if this window should suspend reading. */
-int
-server_window_backoff(struct window_pane *wp)
-{
- struct client *c;
- u_int i;
-
- if (!window_pane_visible(wp))
- return (0);
-
- for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
- c = ARRAY_ITEM(&clients, i);
- if (c == NULL || c->session == NULL)
- continue;
- if ((c->flags & (CLIENT_SUSPENDED|CLIENT_DEAD)) != 0)
- continue;
- if (c->session->curw->window != wp->window)
- continue;
-
- if (EVBUFFER_LENGTH(c->tty.event->output) > BACKOFF_THRESHOLD)
- return (1);
- }
- return (0);
-}
-
/* Window functions that need to happen every loop. */
void
server_window_loop(void)
@@ -69,17 +44,6 @@ server_window_loop(void)
if (w == NULL)
continue;
- TAILQ_FOREACH(wp, &w->panes, entry) {
- if (wp->fd == -1)
- continue;
- if (!(wp->flags & PANE_FREEZE)) {
- if (server_window_backoff(wp))
- bufferevent_disable(wp->event, EV_READ);
- else
- bufferevent_enable(wp->event, EV_READ);
- }
- }
-
for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
s = ARRAY_ITEM(&sessions, j);
if (s == NULL)
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index d40115d0e44..52340be36b1 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.236 2010/07/24 20:11:59 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.237 2010/08/11 07:34:43 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -59,8 +59,8 @@ extern char **environ;
/* Automatic name refresh interval, in milliseconds. */
#define NAME_INTERVAL 500
-/* Maximum data to buffer for output before suspending reading from panes. */
-#define BACKOFF_THRESHOLD 1024
+/* Maximum data to buffer for output before suspending writing to a tty. */
+#define BACKOFF_THRESHOLD 16384
/*
* Maximum sizes of strings in message data. Don't forget to bump
@@ -1017,6 +1017,7 @@ struct tty {
#define TTY_UTF8 0x8
#define TTY_STARTED 0x10
#define TTY_OPENED 0x20
+#define TTY_BACKOFF 0x40
int flags;
int term_flags;
@@ -1126,6 +1127,8 @@ struct client {
#define CLIENT_DEAD 0x200
#define CLIENT_BORDERS 0x400
#define CLIENT_READONLY 0x800
+#define CLIENT_BACKOFF 0x1000
+#define CLIENT_REDRAWWINDOW 0x2000
int flags;
struct event identify_timer;
diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c
index 1d64d2555ea..094be0f99bf 100644
--- a/usr.bin/tmux/tty.c
+++ b/usr.bin/tmux/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.88 2010/06/05 16:47:11 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.89 2010/08/11 07:34:43 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -578,7 +578,9 @@ tty_write(void (*cmdfn)(
continue;
if (c->session->curw->window == wp->window) {
- if (c->tty.flags & TTY_FREEZE || c->tty.term == NULL)
+ if (c->tty.term == NULL)
+ continue;
+ if (c->tty.flags & (TTY_FREEZE|TTY_BACKOFF))
continue;
cmdfn(&c->tty, ctx);
}