From 36017fbd3c87aca01dd978f2b65bf634885fd8bc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 5 Dec 2014 12:50:39 +0100 Subject: [PATCH] touchpad: Use remove callback to unlink event listener and stop timers We use 2 mechanisms to unregister the trackpoint event listener depending on device removal order. 1) We have a device_removed callback, if the trackpoint gets removed before the touchpad, this gets called, sees the device being removed is the trackpoint and unregisters the listener 2) If the touchpad gets removed first, then in tp_destroy we unregister the listener 2) May be delayed beyond the destruction of the trackpoint itself if the libinput user has a reference to the libinput_device for the touchpad. When this happens the trackpoint still has an eventlistener at destroy time and an assert triggers. To fix this we must do 2) at the same time as we do 1), so at remove time. While working on this I noticed that the touchpad code was also cancelling timers at destroy time rather then remove time, which means that they may expire between remove and destroy time, and cause events to be emitted from a removed device, so this commit moves the cancelling of the timers to the remove callback as well. Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer --- src/evdev-mt-touchpad-buttons.c | 2 +- src/evdev-mt-touchpad-edge-scroll.c | 2 +- src/evdev-mt-touchpad-tap.c | 2 +- src/evdev-mt-touchpad.c | 24 ++++++++++++++++-------- src/evdev-mt-touchpad.h | 6 +++--- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index cfd6588d..6af3fcf1 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -603,7 +603,7 @@ tp_init_buttons(struct tp_dispatch *tp, } void -tp_destroy_buttons(struct tp_dispatch *tp) +tp_remove_buttons(struct tp_dispatch *tp) { struct tp_touch *t; diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index d68fc686..3684c8a9 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -271,7 +271,7 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device) } void -tp_destroy_edge_scroll(struct tp_dispatch *tp) +tp_remove_edge_scroll(struct tp_dispatch *tp) { struct tp_touch *t; diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index a38edbe3..c34b2034 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -720,7 +720,7 @@ tp_init_tap(struct tp_dispatch *tp) } void -tp_destroy_tap(struct tp_dispatch *tp) +tp_remove_tap(struct tp_dispatch *tp) { libinput_timer_cancel(&tp->tap.timer); } diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index cd76e4f3..32d6eaca 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -512,9 +512,9 @@ tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time) } static void -tp_destroy_scroll(struct tp_dispatch *tp) +tp_remove_scroll(struct tp_dispatch *tp) { - tp_destroy_edge_scroll(tp); + tp_remove_edge_scroll(tp); } static void @@ -668,7 +668,7 @@ tp_process(struct evdev_dispatch *dispatch, } static void -tp_destroy_sendevents(struct tp_dispatch *tp) +tp_remove_sendevents(struct tp_dispatch *tp) { libinput_timer_cancel(&tp->sendevents.trackpoint_timer); @@ -677,16 +677,24 @@ tp_destroy_sendevents(struct tp_dispatch *tp) &tp->sendevents.trackpoint_listener); } +static void +tp_remove(struct evdev_dispatch *dispatch) +{ + struct tp_dispatch *tp = + (struct tp_dispatch*)dispatch; + + tp_remove_tap(tp); + tp_remove_buttons(tp); + tp_remove_sendevents(tp); + tp_remove_scroll(tp); +} + static void tp_destroy(struct evdev_dispatch *dispatch) { struct tp_dispatch *tp = (struct tp_dispatch*)dispatch; - tp_destroy_tap(tp); - tp_destroy_buttons(tp); - tp_destroy_sendevents(tp); - tp_destroy_scroll(tp); free(tp->touches); free(tp); @@ -858,7 +866,7 @@ tp_tag_device(struct evdev_device *device, static struct evdev_dispatch_interface tp_interface = { tp_process, - NULL, /* remove */ + tp_remove, tp_destroy, tp_device_added, tp_device_removed, diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index da9c0914..14502882 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -287,7 +287,7 @@ int tp_init_tap(struct tp_dispatch *tp); void -tp_destroy_tap(struct tp_dispatch *tp); +tp_remove_tap(struct tp_dispatch *tp); int tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device); @@ -298,7 +298,7 @@ tp_init_softbuttons(struct tp_dispatch *tp, double topbutton_size_mult); void -tp_destroy_buttons(struct tp_dispatch *tp); +tp_remove_buttons(struct tp_dispatch *tp); int tp_process_button(struct tp_dispatch *tp, @@ -338,7 +338,7 @@ int tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device); void -tp_destroy_edge_scroll(struct tp_dispatch *tp); +tp_remove_edge_scroll(struct tp_dispatch *tp); void tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time);