diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 13:36:04 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 13:37:25 +0300 |
| commit | aedd863e6f66fd446227e9b107bc9c1970092634 (patch) | |
| tree | 27836fd18bfbe09ee7c8f9fa8cc14308b9f04fa9 /src/common/backend.c | |
| parent | b20263cf9b6d85c7e5919497b5d36b4c81463b15 (diff) | |
timers: drop retired surface timer ids
yasl_surface_del_timer zeroed its entry and kept it. A one-shot surface
timer that fired stayed in the surface's id list until the surface was
destroyed. A client that re-arms a one-shot timer, such as a cursor
blink, grew the list without bound, and each delete scanned all of it.
Delete now removes the entry. Before the list grows, add drops the ids
that the loop has retired. The list holds only armed timers.
Delete now returns false for a timer that already retired, as
yasl_loop_del_timer does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/common/backend.c')
| -rw-r--r-- | src/common/backend.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/common/backend.c b/src/common/backend.c index ad4d908..4c755bd 100644 --- a/src/common/backend.c +++ b/src/common/backend.c @@ -1,4 +1,5 @@ #include "backend.h" +#include "loop.h" #include <errno.h> #include <stdlib.h> @@ -369,6 +370,15 @@ yasl_timer_id yasl_surface_add_timer(struct yasl_surface *s, uint64_t interval_n yasl_timer_id id = yasl_loop_add_timer(s->display->loop, interval_ns, cb, ud); if (!id) return 0; + /* A one-shot timer retires itself in the loop. Drop retired ids before + * the list grows, so the list holds only armed timers. */ + if (s->timer_count >= s->timer_capacity) { + int kept = 0; + for (int i = 0; i < s->timer_count; i++) + if (yasl_loop_timer_armed(s->display->loop, s->timers[i])) + s->timers[kept++] = s->timers[i]; + s->timer_count = kept; + } if (s->timer_count >= s->timer_capacity) { int new_cap = s->timer_capacity ? s->timer_capacity * 2 : 4; yasl_timer_id *nt = realloc(s->timers, (size_t)new_cap * sizeof(*nt)); @@ -388,10 +398,8 @@ bool yasl_surface_del_timer(struct yasl_surface *s, yasl_timer_id id) if (!s || id == 0) return false; for (int i = 0; i < s->timer_count; i++) { if (s->timers[i] == id) { - s->timers[i] = 0; - if (s->display && s->display->loop) - yasl_loop_del_timer(s->display->loop, id); - return true; + s->timers[i] = s->timers[--s->timer_count]; + return s->display && yasl_loop_del_timer(s->display->loop, id); } } return false; |
