mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-05 06:20:26 +01:00
timer: always restart the timer loop when we called one of them
If a timer_func causes the removal or addition of a different timer, our tmp pointer from the list_for_each_safe may not be valid anymore. This was triggered by having the debounce code trigger a middle button state change, which caused that timer to be cancelled. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
696fdff247
commit
6d0edf9d07
1 changed files with 13 additions and 2 deletions
15
src/timer.c
15
src/timer.c
|
|
@ -128,7 +128,7 @@ static void
|
|||
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;
|
||||
|
|
@ -144,7 +144,8 @@ libinput_timer_handler(void *data)
|
|||
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;
|
||||
|
||||
|
|
@ -153,6 +154,16 @@ libinput_timer_handler(void *data)
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue