summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/backend.c16
-rw-r--r--src/common/loop.c9
-rw-r--r--src/common/loop.h2
3 files changed, 23 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;
diff --git a/src/common/loop.c b/src/common/loop.c
index 3815e91..a63df16 100644
--- a/src/common/loop.c
+++ b/src/common/loop.c
@@ -208,6 +208,15 @@ static void timer_cleanup_deleted(struct yasl_loop *l)
l->timer_count = dest;
}
+bool yasl_loop_timer_armed(const struct yasl_loop *l, yasl_timer_id id)
+{
+ if (!l || id == 0) return false;
+ for (int i = 0; i < l->timer_count; i++)
+ if (l->timers[i].id == id)
+ return !l->timers[i].deleted;
+ return false;
+}
+
int yasl_loop_next_timeout_ms(const struct yasl_loop *l)
{
if (!l || l->timer_count <= 0) return -1;
diff --git a/src/common/loop.h b/src/common/loop.h
index 579fa2c..663417a 100644
--- a/src/common/loop.h
+++ b/src/common/loop.h
@@ -4,5 +4,7 @@
#include "yasl/loop.h"
int yasl_loop_next_timeout_ms(const struct yasl_loop *l);
+/* Whether id is armed: added, not deleted, and not retired by its callback. */
+bool yasl_loop_timer_armed(const struct yasl_loop *l, yasl_timer_id id);
#endif /* YASL_COMMON_LOOP_H */