mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-07 11:58:04 +02: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)
|
libinput_timer_handler(void *data)
|
||||||
{
|
{
|
||||||
struct libinput *libinput = data;
|
struct libinput *libinput = data;
|
||||||
struct libinput_timer *timer, *tmp;
|
struct libinput_timer *timer;
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
uint64_t discard;
|
uint64_t discard;
|
||||||
int r;
|
int r;
|
||||||
|
|
@ -132,7 +132,8 @@ libinput_timer_handler(void *data)
|
||||||
if (now == 0)
|
if (now == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_for_each_safe(timer, tmp, &libinput->timer.list, link) {
|
restart:
|
||||||
|
list_for_each(timer, &libinput->timer.list, link) {
|
||||||
if (timer->expire == 0)
|
if (timer->expire == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -141,6 +142,16 @@ libinput_timer_handler(void *data)
|
||||||
as timer_func may re-arm it */
|
as timer_func may re-arm it */
|
||||||
libinput_timer_cancel(timer);
|
libinput_timer_cancel(timer);
|
||||||
timer->timer_func(now, timer->timer_func_data);
|
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