summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server-window.c27
-rw-r--r--tmux.h3
2 files changed, 29 insertions, 1 deletions
diff --git a/server-window.c b/server-window.c
index 969395c8..122ca092 100644
--- a/server-window.c
+++ b/server-window.c
@@ -22,6 +22,7 @@
#include "tmux.h"
+int server_window_backoff(struct window_pane *);
int server_window_check_bell(struct session *, struct window *);
int server_window_check_activity(struct session *, struct window *);
int server_window_check_content(
@@ -44,7 +45,9 @@ server_window_prepare(void)
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
- events = POLLIN;
+ events = 0;
+ if (!server_window_backoff(wp))
+ events |= POLLIN;
if (BUFFER_USED(wp->out) > 0)
events |= POLLOUT;
server_poll_add(
@@ -61,6 +64,28 @@ server_window_prepare(void)
}
}
+/* 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->session->curw->window != wp->window)
+ continue;
+ if (BUFFER_USED(c->tty.out) > BACKOFF_THRESHOLD)
+ return (1);
+ }
+ return (0);
+}
+
/* Process a single window pane event. */
void
server_window_callback(int fd, int events, void *data)
diff --git a/tmux.h b/tmux.h
index e270e821..41ace3a8 100644
--- a/tmux.h
+++ b/tmux.h
@@ -65,6 +65,9 @@ extern char **environ;
/* Maximum poll timeout (when attached). */
#define POLL_TIMEOUT 50
+/* Maximum data to buffer for output before suspending reading from panes. */
+#define BACKOFF_THRESHOLD 1024
+
/*
* Maximum sizes of strings in message data. Don't forget to bump
* PROTOCOL_VERSION if any of these change!