[PATCH libinput] timer: add a timer name to each timer

Peter Hutterer peter.hutterer at who-t.net
Mon Jul 3 03:05:07 UTC 2017


So we have something useful to print when we trigger an error in the timer
code.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-middle-button.c           |  7 +++++++
 src/evdev-mt-touchpad-buttons.c     | 15 ++++++++++++++-
 src/evdev-mt-touchpad-edge-scroll.c | 14 +++++++++++++-
 src/evdev-mt-touchpad-gestures.c    |  7 +++++++
 src/evdev-mt-touchpad-tap.c         |  7 +++++++
 src/evdev-mt-touchpad.c             | 16 ++++++++++++++++
 src/evdev.c                         |  9 +++++++++
 src/timer.c                         | 18 +++++++++++++++---
 src/timer.h                         |  5 +++++
 test/test-misc.c                    | 38 +++++++++++++++++++++++++++++++++++++
 10 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/src/evdev-middle-button.c b/src/evdev-middle-button.c
index 78a19ef8..039fcaff 100644
--- a/src/evdev-middle-button.c
+++ b/src/evdev-middle-button.c
@@ -696,8 +696,15 @@ evdev_init_middlebutton(struct evdev_device *device,
 			bool enable,
 			bool want_config)
 {
+	char timer_name[64];
+
+	snprintf(timer_name,
+		 sizeof(timer_name),
+		 "%s middlebutton",
+		 evdev_device_get_sysname(device));
 	libinput_timer_init(&device->middlebutton.timer,
 			    evdev_libinput_context(device),
+			    timer_name,
 			    evdev_middlebutton_handle_timeout,
 			    device);
 	device->middlebutton.enabled_default = enable;
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index c437ddf2..929eab52 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -832,6 +832,7 @@ tp_init_buttons(struct tp_dispatch *tp,
 {
 	struct tp_touch *t;
 	const struct input_absinfo *absinfo_x, *absinfo_y;
+	int i;
 
 	tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
 							INPUT_PROP_BUTTONPAD);
@@ -870,10 +871,20 @@ tp_init_buttons(struct tp_dispatch *tp,
 
 	tp_init_middlebutton_emulation(tp, device);
 
+	i = 0;
 	tp_for_each_touch(tp, t) {
+		char timer_name[64];
+		i++;
+
+		snprintf(timer_name,
+			 sizeof(timer_name),
+			 "%s (%d) button",
+			 evdev_device_get_sysname(device),
+			 i);
 		t->button.state = BUTTON_STATE_NONE;
 		libinput_timer_init(&t->button.timer,
 				    tp_libinput_context(tp),
+				    timer_name,
 				    tp_button_handle_timeout, t);
 	}
 }
@@ -883,8 +894,10 @@ tp_remove_buttons(struct tp_dispatch *tp)
 {
 	struct tp_touch *t;
 
-	tp_for_each_touch(tp, t)
+	tp_for_each_touch(tp, t) {
 		libinput_timer_cancel(&t->button.timer);
+		libinput_timer_destroy(&t->button.timer);
+	}
 }
 
 static int
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index 6174b738..4704c68e 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -280,6 +280,7 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device)
 	bool want_horiz_scroll = true;
 	struct device_coords edges;
 	struct phys_coords mm = { 0.0, 0.0 };
+	int i;
 
 	evdev_device_get_size(device, &width, &height);
 	/* Touchpads smaller than 40mm are not tall enough to have a
@@ -302,10 +303,19 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device)
 	else
 		tp->scroll.bottom_edge = INT_MAX;
 
+	i = 0;
 	tp_for_each_touch(tp, t) {
+		char timer_name[64];
+
+		snprintf(timer_name,
+			 sizeof(timer_name),
+			 "%s (%d) edgescroll",
+			 evdev_device_get_sysname(device),
+			 i);
 		t->scroll.direction = -1;
 		libinput_timer_init(&t->scroll.timer,
 				    tp_libinput_context(tp),
+				    timer_name,
 				    tp_edge_scroll_handle_timeout, t);
 	}
 }
@@ -315,8 +325,10 @@ tp_remove_edge_scroll(struct tp_dispatch *tp)
 {
 	struct tp_touch *t;
 
-	tp_for_each_touch(tp, t)
+	tp_for_each_touch(tp, t) {
 		libinput_timer_cancel(&t->scroll.timer);
+		libinput_timer_destroy(&t->scroll.timer);
+	}
 }
 
 void
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c
index a20b26d4..e3bca1f4 100644
--- a/src/evdev-mt-touchpad-gestures.c
+++ b/src/evdev-mt-touchpad-gestures.c
@@ -622,6 +622,8 @@ tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time)
 void
 tp_init_gesture(struct tp_dispatch *tp)
 {
+	char timer_name[64];
+
 	/* two-finger scrolling is always enabled, this flag just
 	 * decides whether we detect pinch. semi-mt devices are too
 	 * unreliable to do pinch gestures. */
@@ -629,8 +631,13 @@ tp_init_gesture(struct tp_dispatch *tp)
 
 	tp->gesture.state = GESTURE_STATE_NONE;
 
+	snprintf(timer_name,
+		 sizeof(timer_name),
+		 "%s gestures",
+		 evdev_device_get_sysname(tp->device));
 	libinput_timer_init(&tp->gesture.finger_count_switch_timer,
 			    tp_libinput_context(tp),
+			    timer_name,
 			    tp_gesture_finger_count_switch_timeout, tp);
 }
 
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 3ab33166..f01487fe 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -1106,6 +1106,8 @@ tp_tap_config_get_default_draglock_enabled(struct libinput_device *device)
 void
 tp_init_tap(struct tp_dispatch *tp)
 {
+	char timer_name[64];
+
 	tp->tap.config.count = tp_tap_config_count;
 	tp->tap.config.set_enabled = tp_tap_config_set_enabled;
 	tp->tap.config.get_enabled = tp_tap_config_is_enabled;
@@ -1128,8 +1130,13 @@ tp_init_tap(struct tp_dispatch *tp)
 	tp->tap.drag_enabled = tp_drag_default(tp->device);
 	tp->tap.drag_lock_enabled = tp_drag_lock_default(tp->device);
 
+	snprintf(timer_name,
+		 sizeof(timer_name),
+		 "%s tap",
+		 evdev_device_get_sysname(tp->device));
 	libinput_timer_init(&tp->tap.timer,
 			    tp_libinput_context(tp),
+			    timer_name,
 			    tp_tap_handle_timeout, tp);
 }
 
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 2d39e18d..cf291a71 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1347,6 +1347,10 @@ tp_interface_destroy(struct evdev_dispatch *dispatch)
 {
 	struct tp_dispatch *tp = tp_dispatch(dispatch);
 
+	libinput_timer_destroy(&tp->palm.trackpoint_timer);
+	libinput_timer_destroy(&tp->dwt.keyboard_timer);
+	libinput_timer_destroy(&tp->tap.timer);
+	libinput_timer_destroy(&tp->gesture.finger_count_switch_timer);
 	free(tp->touches);
 	free(tp);
 }
@@ -2314,12 +2318,24 @@ static void
 tp_init_sendevents(struct tp_dispatch *tp,
 		   struct evdev_device *device)
 {
+	char timer_name[64];
+
+	snprintf(timer_name,
+		 sizeof(timer_name),
+		  "%s trackpoint",
+		  evdev_device_get_sysname(device));
 	libinput_timer_init(&tp->palm.trackpoint_timer,
 			    tp_libinput_context(tp),
+			    timer_name,
 			    tp_trackpoint_timeout, tp);
 
+	snprintf(timer_name,
+		 sizeof(timer_name),
+		 "%s keyboard",
+		 evdev_device_get_sysname(device));
 	libinput_timer_init(&tp->dwt.keyboard_timer,
 			    tp_libinput_context(tp),
+			    timer_name,
 			    tp_keyboard_timeout, tp);
 }
 
diff --git a/src/evdev.c b/src/evdev.c
index a6804149..3e8677bf 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1583,8 +1583,15 @@ static void
 evdev_init_button_scroll(struct evdev_device *device,
 			 void (*change_scroll_method)(struct evdev_device *))
 {
+	char timer_name[64];
+
+	snprintf(timer_name,
+		 sizeof(timer_name),
+		 "%s btnscroll",
+		 evdev_device_get_sysname(device));
 	libinput_timer_init(&device->scroll.timer,
 			    evdev_libinput_context(device),
+			    timer_name,
 			    evdev_button_scroll_timeout, device);
 	device->scroll.config.get_methods = evdev_scroll_get_methods;
 	device->scroll.config.set_method = evdev_scroll_set_method;
@@ -3494,6 +3501,8 @@ evdev_device_destroy(struct evdev_device *device)
 
 	free(device->output_name);
 	filter_destroy(device->pointer.filter);
+	libinput_timer_destroy(&device->scroll.timer);
+	libinput_timer_destroy(&device->middlebutton.timer);
 	libinput_seat_unref(device->base.seat);
 	libevdev_free(device->evdev);
 	udev_device_unref(device->udev_device);
diff --git a/src/timer.c b/src/timer.c
index 4a7b43a8..99201ae1 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -34,15 +34,25 @@
 #include "timer.h"
 
 void
-libinput_timer_init(struct libinput_timer *timer, struct libinput *libinput,
+libinput_timer_init(struct libinput_timer *timer,
+		    struct libinput *libinput,
+		    const char *timer_name,
 		    void (*timer_func)(uint64_t now, void *timer_func_data),
 		    void *timer_func_data)
 {
 	timer->libinput = libinput;
+	if (timer_name)
+		timer->timer_name = strdup(timer_name);
 	timer->timer_func = timer_func;
 	timer->timer_func_data = timer_func_data;
 }
 
+void
+libinput_timer_destroy(struct libinput_timer *timer)
+{
+	free(timer->timer_name);
+}
+
 static void
 libinput_timer_arm_timer_fd(struct libinput *libinput)
 {
@@ -76,12 +86,14 @@ libinput_timer_set_flags(struct libinput_timer *timer,
 	if (expire < now) {
 		if ((flags & TIMER_FLAG_ALLOW_NEGATIVE) == 0)
 			log_bug_libinput(timer->libinput,
-					 "timer: offset negative (-%" PRIu64 ")\n",
+					 "timer %s: offset negative (-%" PRIu64 ")\n",
+					 timer->timer_name ? timer->timer_name : "",
 					 now - expire);
 	} else if ((expire - now) > ms2us(5000)) {
 		log_bug_libinput(timer->libinput,
-				 "timer: offset more than 5s, now %"
+				 "timer %s: offset more than 5s, now %"
 				 PRIu64 " expire %" PRIu64 "\n",
+				 timer->timer_name ? timer->timer_name : "",
 				 now, expire);
 	}
 #endif
diff --git a/src/timer.h b/src/timer.h
index 93d684ab..0190766a 100644
--- a/src/timer.h
+++ b/src/timer.h
@@ -32,6 +32,7 @@ struct libinput;
 
 struct libinput_timer {
 	struct libinput *libinput;
+	char *timer_name;
 	struct list link;
 	uint64_t expire; /* in absolute us CLOCK_MONOTONIC */
 	void (*timer_func)(uint64_t now, void *timer_func_data);
@@ -40,9 +41,13 @@ struct libinput_timer {
 
 void
 libinput_timer_init(struct libinput_timer *timer, struct libinput *libinput,
+		    const char *timer_name,
 		    void (*timer_func)(uint64_t now, void *timer_func_data),
 		    void *timer_func_data);
 
+void
+libinput_timer_destroy(struct libinput_timer *timer);
+
 /* Set timer expire time, in absolute us CLOCK_MONOTONIC */
 void
 libinput_timer_set(struct libinput_timer *timer, uint64_t expire);
diff --git a/test/test-misc.c b/test/test-misc.c
index e55daed4..f3d6b5f9 100644
--- a/test/test-misc.c
+++ b/test/test-misc.c
@@ -1280,6 +1280,42 @@ START_TEST(library_version)
 }
 END_TEST
 
+static void timer_offset_warning(struct libinput *libinput,
+				 enum libinput_log_priority priority,
+				 const char *format,
+				 va_list args)
+{
+	int *warning_triggered = (int*)libinput_get_user_data(libinput);
+
+	if (priority == LIBINPUT_LOG_PRIORITY_ERROR &&
+	    strstr(format, "offset negative"))
+		(*warning_triggered)++;
+}
+
+START_TEST(timer_offset_bug_warning)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput *li = dev->libinput;
+	int warning_triggered = 0;
+
+	litest_enable_tap(dev->libinput_device);
+	litest_drain_events(li);
+
+	litest_touch_down(dev, 0, 50, 50);
+	litest_touch_up(dev, 0);
+
+	litest_timeout_tap();
+
+	libinput_set_user_data(li, &warning_triggered);
+	libinput_log_set_handler(li, timer_offset_warning);
+	libinput_dispatch(li);
+
+	/* triggered for touch down and touch up */
+	ck_assert_int_eq(warning_triggered, 2);
+	litest_restore_log_handler(li);
+}
+END_TEST
+
 void
 litest_setup_tests_misc(void)
 {
@@ -1298,6 +1334,8 @@ litest_setup_tests_misc(void)
 	litest_add_no_device("context:refcount", context_ref_counting);
 	litest_add_no_device("config:status string", config_status_string);
 
+	litest_add_for_device("timer:offset-warning", timer_offset_bug_warning, LITEST_SYNAPTICS_TOUCHPAD);
+
 	litest_add_no_device("misc:matrix", matrix_helpers);
 	litest_add_no_device("misc:ratelimit", ratelimit_helpers);
 	litest_add_no_device("misc:parser", dpi_parser);
-- 
2.13.0



More information about the wayland-devel mailing list