From 6ee215a7797cbb15aed6136ccfcaf5daff5ae654 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 12 Feb 2017 19:46:13 -0500 Subject: combine flushes when reading large amounts of data on linux at least, you can only read 4096 bytes of data from a pty, so large writes would cause a lot of redraws --- src/loop.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/loop.h | 1 + src/pty-unix.c | 14 +++++++++++++- src/pty-unix.h | 2 ++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/loop.c b/src/loop.c index f37c431..b6b5ef1 100644 --- a/src/loop.c +++ b/src/loop.c @@ -17,9 +17,17 @@ struct runes_loop_timer_data { void (*cb)(void*); }; +struct runes_loop_idle_data { + struct event *event; + void *t; + void (*cb)(void*); +}; + static void runes_loop_work_cb(evutil_socket_t fd, short what, void *arg); static void runes_loop_timer_cb(evutil_socket_t fd, short what, void *arg); +static void runes_loop_idle_cb(evutil_socket_t fd, short what, void *arg); static void runes_loop_free_timer_data(struct runes_loop_timer_data *data); +static void runes_loop_free_idle_data(struct runes_loop_idle_data *data); RunesLoop *runes_loop_new() { @@ -27,6 +35,7 @@ RunesLoop *runes_loop_new() loop = calloc(1, sizeof(RunesLoop)); loop->base = event_base_new(); + event_base_priority_init(loop->base, 3); return loop; } @@ -86,6 +95,24 @@ void runes_loop_timer_clear(RunesLoop *loop, void *arg) runes_loop_free_timer_data(data); } +void runes_loop_at_idle(RunesLoop *loop, void *t, void (*cb)(void*)) +{ + struct runes_loop_idle_data *data; + struct timeval timeout; + + data = malloc(sizeof(struct runes_loop_idle_data)); + data->event = event_new(loop->base, -1, 0, runes_loop_idle_cb, data); + data->t = t; + data->cb = cb; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + event_priority_set(data->event, 2); + + event_add(data->event, &timeout); +} + void runes_loop_delete(RunesLoop *loop) { event_base_free(loop->base); @@ -121,9 +148,27 @@ static void runes_loop_timer_cb(evutil_socket_t fd, short what, void *arg) runes_loop_free_timer_data(data); } +static void runes_loop_idle_cb(evutil_socket_t fd, short what, void *arg) +{ + struct runes_loop_idle_data *data = arg; + + UNUSED(fd); + UNUSED(what); + + data->cb(data->t); + + runes_loop_free_idle_data(data); +} + static void runes_loop_free_timer_data(struct runes_loop_timer_data *data) { event_free(data->event); free(data->timeout); free(data); } + +static void runes_loop_free_idle_data(struct runes_loop_idle_data *data) +{ + event_free(data->event); + free(data); +} diff --git a/src/loop.h b/src/loop.h index 92d6cf9..72dbcb0 100644 --- a/src/loop.h +++ b/src/loop.h @@ -15,6 +15,7 @@ void runes_loop_start_work( void *runes_loop_timer_set( RunesLoop *loop, int timeout, void *t, void (*cb)(void*)); void runes_loop_timer_clear(RunesLoop *loop, void *arg); +void runes_loop_at_idle(RunesLoop *loop, void *t, void (*cb)(void*)); void runes_loop_delete(RunesLoop *loop); #endif diff --git a/src/pty-unix.c b/src/pty-unix.c index 6cc4996..d712aad 100644 --- a/src/pty-unix.c +++ b/src/pty-unix.c @@ -20,6 +20,7 @@ extern char **environ; static int runes_pty_input_cb(void *t); +static void runes_pty_flush_cb(void *t); RunesPty *runes_pty_new() { @@ -164,7 +165,10 @@ static int runes_pty_input_cb(void *t) ((RunesTerm *)t)->scr, pty->readbuf, to_process); pty->remaininglen = to_process - processed; memmove(pty->readbuf, pty->readbuf + processed, pty->remaininglen); - runes_window_flush(t); + if (!pty->scheduled_flush) { + runes_loop_at_idle(((RunesTerm *)t)->loop, t, runes_pty_flush_cb); + pty->scheduled_flush = 1; + } return 1; } @@ -175,3 +179,11 @@ static int runes_pty_input_cb(void *t) return 0; } } + +static void runes_pty_flush_cb(void *t) +{ + RunesPty *pty = ((RunesTerm *)t)->pty; + + runes_window_flush(t); + pty->scheduled_flush = 0; +} diff --git a/src/pty-unix.h b/src/pty-unix.h index 8894072..553be12 100644 --- a/src/pty-unix.h +++ b/src/pty-unix.h @@ -11,6 +11,8 @@ struct runes_pty { char readbuf[RUNES_READ_BUFFER_LENGTH]; int readlen; int remaininglen; + + int scheduled_flush: 1; }; RunesPty *runes_pty_new(void); -- cgit v1.2.3-54-g00ecf