mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-21 14:30:36 +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>
(cherry picked from commit 6d0edf9d07)
This commit is contained in:
parent
cfb0a39aba
commit
582ce30d27
1 changed files with 13 additions and 2 deletions
15
src/timer.c
15
src/timer.c
|
|
@ -116,7 +116,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;
|
||||
|
|
@ -132,7 +132,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;
|
||||
|
||||
|
|
@ -141,6 +142,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