mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Apply UPDATE_DELAY in arrears, not in advance.
The original aim of the rate limit was to avoid having too many updates per second. I implemented this by a deferment mechanism: when any change occurs that makes the terminal want an update, it instead sets a timer to go off after UPDATE_DELAY (1/50 second), and does the update at the end of that interval. Now it's done the other way round: if there has not been an update within the last UPDATE_DELAY, then we can simply do an update _right now_, in immediate response to whatever triggered it. And _then_ we set a timer to track a cooldown period, within which any further requests for updates will be deferred until the end of the cooldown. This mechanism should still rate-limit updates, but now the latency in normal interactive use should be lowered, because terminal updates in response to keystrokes (which typically arrive separated by more than UPDATE_DELAY) can now each be enacted as soon as possible after the triggering keystroke. This also reverses (in the common case) the slowdown of non-textual window modifications introduced by the previous commit, in which lots of them were brought under the umbrella of term_update and therefore became subject to UPDATE_DELAY. Now they'll only be delayed in conditions of high traffic, and not in interactive use.
This commit is contained in:
parent
d74308e90e
commit
334688db81
32
terminal.c
32
terminal.c
@ -1187,41 +1187,58 @@ static void check_line_size(Terminal *term, termline *line)
|
|||||||
|
|
||||||
static void term_schedule_tblink(Terminal *term);
|
static void term_schedule_tblink(Terminal *term);
|
||||||
static void term_schedule_cblink(Terminal *term);
|
static void term_schedule_cblink(Terminal *term);
|
||||||
|
static void term_update_callback(void *ctx);
|
||||||
|
|
||||||
static void term_timer(void *ctx, unsigned long now)
|
static void term_timer(void *ctx, unsigned long now)
|
||||||
{
|
{
|
||||||
Terminal *term = (Terminal *)ctx;
|
Terminal *term = (Terminal *)ctx;
|
||||||
bool update = false;
|
|
||||||
|
|
||||||
if (term->tblink_pending && now == term->next_tblink) {
|
if (term->tblink_pending && now == term->next_tblink) {
|
||||||
term->tblinker = !term->tblinker;
|
term->tblinker = !term->tblinker;
|
||||||
term->tblink_pending = false;
|
term->tblink_pending = false;
|
||||||
term_schedule_tblink(term);
|
term_schedule_tblink(term);
|
||||||
update = true;
|
term->window_update_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (term->cblink_pending && now == term->next_cblink) {
|
if (term->cblink_pending && now == term->next_cblink) {
|
||||||
term->cblinker = !term->cblinker;
|
term->cblinker = !term->cblinker;
|
||||||
term->cblink_pending = false;
|
term->cblink_pending = false;
|
||||||
term_schedule_cblink(term);
|
term_schedule_cblink(term);
|
||||||
update = true;
|
term->window_update_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (term->in_vbell && now == term->vbell_end) {
|
if (term->in_vbell && now == term->vbell_end) {
|
||||||
term->in_vbell = false;
|
term->in_vbell = false;
|
||||||
update = true;
|
term->window_update_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update ||
|
if (term->window_update_cooldown &&
|
||||||
(term->window_update_pending && now == term->next_update))
|
now == term->window_update_cooldown_end) {
|
||||||
|
term->window_update_cooldown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (term->window_update_pending)
|
||||||
|
term_update_callback(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void term_update_callback(void *ctx)
|
||||||
|
{
|
||||||
|
Terminal *term = (Terminal *)ctx;
|
||||||
|
if (!term->window_update_pending)
|
||||||
|
return;
|
||||||
|
if (!term->window_update_cooldown) {
|
||||||
term_update(term);
|
term_update(term);
|
||||||
|
term->window_update_cooldown = true;
|
||||||
|
term->window_update_cooldown_end = schedule_timer(
|
||||||
|
UPDATE_DELAY, term_timer, term);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void term_schedule_update(Terminal *term)
|
static void term_schedule_update(Terminal *term)
|
||||||
{
|
{
|
||||||
if (!term->window_update_pending) {
|
if (!term->window_update_pending) {
|
||||||
term->window_update_pending = true;
|
term->window_update_pending = true;
|
||||||
term->next_update = schedule_timer(UPDATE_DELAY, term_timer, term);
|
queue_toplevel_callback(term_update_callback, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1940,6 +1957,7 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win)
|
|||||||
term->wcFromTo_size = 0;
|
term->wcFromTo_size = 0;
|
||||||
|
|
||||||
term->window_update_pending = false;
|
term->window_update_pending = false;
|
||||||
|
term->window_update_cooldown = false;
|
||||||
|
|
||||||
term->bidi_cache_size = 0;
|
term->bidi_cache_size = 0;
|
||||||
term->pre_bidi_cache = term->post_bidi_cache = NULL;
|
term->pre_bidi_cache = term->post_bidi_cache = NULL;
|
||||||
|
14
terminal.h
14
terminal.h
@ -259,11 +259,17 @@ struct terminal_tag {
|
|||||||
bool in_term_out;
|
bool in_term_out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We schedule a window update shortly after receiving terminal
|
* We don't permit window updates too close together, to avoid CPU
|
||||||
* data. This tracks whether one is currently pending.
|
* churn pointlessly redrawing the window faster than the user can
|
||||||
|
* read. So after an update, we set window_update_cooldown = true
|
||||||
|
* and schedule a timer to reset it to false. In between those
|
||||||
|
* times, window updates are not performed, and instead we set
|
||||||
|
* window_update_pending = true, which will remind us to perform
|
||||||
|
* the deferred redraw when the cooldown period ends and
|
||||||
|
* window_update_cooldown is reset to false.
|
||||||
*/
|
*/
|
||||||
bool window_update_pending;
|
bool window_update_pending, window_update_cooldown;
|
||||||
long next_update;
|
long window_update_cooldown_end;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Track pending blinks and tblinks.
|
* Track pending blinks and tblinks.
|
||||||
|
Loading…
Reference in New Issue
Block a user