libinput_timer_handler(void *data)
{
struct libinput *libinput = data;
- struct libinput_timer *timer, *tmp;
+ struct libinput_timer *timer;
uint64_t now;
uint64_t discard;
int r;
if (now == 0)
return;
- list_for_each_safe(timer, tmp, &libinput->timer.list, link) {
+restart:
+ list_for_each(timer, &libinput->timer.list, link) {
if (timer->expire == 0)
continue;
as timer_func may re-arm it */
libinput_timer_cancel(timer);
timer->timer_func(now, timer->timer_func_data);
+
+ /*
+ * Restart the loop. We can't use
+ * list_for_each_safe() here because that only
+ * allows removing one (our) timer per timer_func.
+ * But the timer func may trigger another unrelated
+ * timer to be cancelled and removed, causing a
+ * segfault.
+ */
+ goto restart;
}
}
}