From ba0d0e8bbb970599c1c0a13a27cc8bae71f60185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 23 Mar 2020 19:16:53 +0100 Subject: [PATCH] term: delayed rendering: read timers even though is_armed = false There's a race/chance that we'll have disarmed the delayed rendering timers and still get the call. While it _shouldn't_ be anything to read from the timers, it doesn't hurt to try. And, if the timers *are* readable, not reading them means we'll end up in an infinite FDM loop. --- terminal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/terminal.c b/terminal.c index b39bb8d9..4554ae20 100644 --- a/terminal.c +++ b/terminal.c @@ -396,8 +396,6 @@ fdm_delayed_render(struct fdm *fdm, int fd, int events, void *data) return false; struct terminal *term = data; - if (!term->delayed_render_timer.is_armed) - return true; uint64_t unused; ssize_t ret1 = 0; @@ -412,6 +410,9 @@ fdm_delayed_render(struct fdm *fdm, int fd, int events, void *data) if (errno == EAGAIN) return true; + if (!term->delayed_render_timer.is_armed) + return true; + LOG_ERRNO("failed to read timeout timer"); return false; } @@ -425,13 +426,15 @@ fdm_delayed_render(struct fdm *fdm, int fd, int events, void *data) last = (struct timespec){0}; #endif - render_refresh(term); - /* Reset timers */ struct itimerspec reset = {{0}}; timerfd_settime(term->delayed_render_timer.lower_fd, 0, &reset, NULL); timerfd_settime(term->delayed_render_timer.upper_fd, 0, &reset, NULL); - term->delayed_render_timer.is_armed = false; + + if (term->delayed_render_timer.is_armed) { + term->delayed_render_timer.is_armed = false; + render_refresh(term); + } return true; }