To replace c0-*, add a high watermark to the pty event, and also backoff

when the any of the ttys the pane is going to write to has buffered
enough data.
This commit is contained in:
nicm
2015-05-12 22:40:38 +00:00
parent 37ae8a9e0f
commit 3f4ee98162
3 changed files with 79 additions and 19 deletions

View File

@ -58,6 +58,7 @@ u_int next_window_pane_id;
u_int next_window_id;
u_int next_active_point;
void window_pane_timer_callback(int, short, void *);
void window_pane_read_callback(struct bufferevent *, void *);
void window_pane_error_callback(struct bufferevent *, short, void *);
@ -740,6 +741,9 @@ window_pane_destroy(struct window_pane *wp)
{
window_pane_reset_mode(wp);
if (event_initialized(&wp->timer))
evtimer_del(&wp->timer);
if (wp->fd != -1) {
bufferevent_free(wp->event);
close(wp->fd);
@ -867,28 +871,53 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
wp->event = bufferevent_new(wp->fd, window_pane_read_callback, NULL,
window_pane_error_callback, wp);
bufferevent_setwatermark(wp->event, EV_READ, 0, READ_SIZE);
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
free(cmd);
return (0);
}
void
window_pane_timer_callback(unused int fd, unused short events, void *data)
{
window_pane_read_callback(NULL, data);
}
void
window_pane_read_callback(unused struct bufferevent *bufev, void *data)
{
struct window_pane *wp = data;
char *new_data;
size_t new_size;
struct window_pane *wp = data;
struct evbuffer *evb = wp->event->input;
char *new_data;
size_t new_size, available;
struct client *c;
struct timeval tv;
new_size = EVBUFFER_LENGTH(wp->event->input) - wp->pipe_off;
if (event_initialized(&wp->timer))
evtimer_del(&wp->timer);
log_debug("%%%u has %zu bytes", wp->id, EVBUFFER_LENGTH(evb));
TAILQ_FOREACH(c, &clients, entry) {
if (!tty_client_ready(c, wp))
continue;
available = EVBUFFER_LENGTH(c->tty.event->output);
if (available > READ_BACKOFF)
goto start_timer;
}
new_size = EVBUFFER_LENGTH(evb) - wp->pipe_off;
if (wp->pipe_fd != -1 && new_size > 0) {
new_data = EVBUFFER_DATA(wp->event->input);
new_data = EVBUFFER_DATA(evb);
bufferevent_write(wp->pipe_event, new_data, new_size);
}
input_parse(wp);
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
wp->pipe_off = EVBUFFER_LENGTH(evb);
/*
* If we get here, we're not outputting anymore, so set the silence
@ -897,11 +926,22 @@ window_pane_read_callback(unused struct bufferevent *bufev, void *data)
wp->window->flags |= WINDOW_SILENCE;
if (gettimeofday(&wp->window->silence_timer, NULL) != 0)
fatal("gettimeofday failed.");
return;
start_timer:
log_debug("%%%u backing off (%s %zu > %d)", wp->id, c->ttyname,
available, READ_BACKOFF);
tv.tv_sec = 0;
tv.tv_usec = READ_TIME;
evtimer_set(&wp->timer, window_pane_timer_callback, wp);
evtimer_add(&wp->timer, &tv);
}
void
window_pane_error_callback(
unused struct bufferevent *bufev, unused short what, void *data)
window_pane_error_callback(unused struct bufferevent *bufev, unused short what,
void *data)
{
struct window_pane *wp = data;