[PATCH libinput v2 2/2] touchpad: Use remove callback to unlink event listener and stop timers

Peter Hutterer peter.hutterer at who-t.net
Mon Dec 8 15:36:42 PST 2014


On Mon, Dec 08, 2014 at 10:46:44AM +0100, Hans de Goede wrote:
> 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 <hdegoede at redhat.com>

Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net> for both but see the
comment about calling evdev_suspend first.

Cheers,
   Peter

> ---
>  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 cfd6588..6af3fcf 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 d68fc68..3684c8a 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 a38edbe..c34b203 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 5af0062..5938080 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -517,9 +517,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
> @@ -673,7 +673,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);
>  
> @@ -683,15 +683,23 @@ tp_destroy_sendevents(struct tp_dispatch *tp)
>  }
>  
>  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);
> @@ -863,7 +871,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 da9c091..1450288 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);
> -- 
> 2.1.0
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 


More information about the wayland-devel mailing list