summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2021-09-14 19:53:04 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2021-09-15 09:03:21 +1000
commit6c869071fbf355c544b2fa2c4ed53ded36d450d6 (patch)
tree9fe8707ca90b15cacb583de62c7ccf25ab034c13
parentca0c2470d73ccaeaf9cd2557939c8f37c0f3e55a (diff)
downloadlibinput-6c869071fbf355c544b2fa2c4ed53ded36d450d6.tar.gz
touchpad: fix leak when the touchpad is removed before the dwt keyboard
If a touchpad is removed before its dwt-paired keyboard, we're leaking the keyboard struct. Fix this by cleaning up properly when our device is removed. This is the cause of many failed tests in the udev backend tests during the CI valgrind run. Because we're testing the udev backend it will add any devices created by tests run in parallel, some of which are keyboard devices. Depening on the test completions, the keyboards may or may not get removed before this device. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--src/evdev-mt-touchpad.c6
-rw-r--r--test/test-touchpad.c18
2 files changed, 24 insertions, 0 deletions
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index c97452a8..9ba7604d 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1999,9 +1999,15 @@ static void
tp_interface_remove(struct evdev_dispatch *dispatch)
{
struct tp_dispatch *tp = tp_dispatch(dispatch);
+ struct evdev_paired_keyboard *kbd;
libinput_timer_cancel(&tp->arbitration.arbitration_timer);
+ list_for_each_safe(kbd, &tp->dwt.paired_keyboard_list, link) {
+ evdev_paired_keyboard_destroy(kbd);
+ }
+ tp->dwt.keyboard_active = false;
+
tp_remove_tap(tp);
tp_remove_buttons(tp);
tp_remove_sendevents(tp);
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index b7b34598..4bd14752 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -5119,6 +5119,23 @@ START_TEST(touchpad_dwt_multiple_keyboards)
}
END_TEST
+START_TEST(touchpad_dwt_remove_before_keyboard)
+{
+ struct litest_device *keyboard = litest_current_device();
+ struct litest_device *touchpad;
+ struct libinput *li = keyboard->libinput;
+
+ touchpad = litest_add_device(li, LITEST_SYNAPTICS_RMI4);
+ ck_assert(has_disable_while_typing(touchpad));
+
+ libinput_dispatch(li);
+
+ /* remove the touchpad before the keyboard.
+ * this test can fail in valgrind only */
+ litest_delete_device(touchpad);
+}
+END_TEST
+
START_TEST(touchpad_dwt_multiple_keyboards_bothkeys)
{
struct litest_device *touchpad = litest_current_device();
@@ -7293,6 +7310,7 @@ TEST_COLLECTION(touchpad)
litest_add_for_device(touchpad_dwt_multiple_keyboards_bothkeys, LITEST_SYNAPTICS_I2C);
litest_add_for_device(touchpad_dwt_multiple_keyboards_bothkeys_modifier, LITEST_SYNAPTICS_I2C);
litest_add_ranged_for_device(touchpad_dwt_multiple_keyboards_remove, LITEST_SYNAPTICS_I2C, &twice);
+ litest_add_for_device(touchpad_dwt_remove_before_keyboard, LITEST_KEYBOARD);
litest_add(touchpad_thumb_lower_area_movement, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_thumb_lower_area_movement_rethumb, LITEST_CLICKPAD, LITEST_ANY);