[PATCH weston 2/2] clients: consolidate timer code part 2

Pekka Paalanen ppaalanen at gmail.com
Fri Mar 9 11:44:01 UTC 2018


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

Continue moving bits to use toytimer instead of carelessly open-coded
equivalent. Many of the copies were flawed against the race mentioned
in toytimer_fire().

This patch handles window.c's key repeat, confine demo, and
desktop-shell panel clock.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 clients/confine.c       | 35 +++++++----------------------------
 clients/desktop-shell.c | 35 +++++++----------------------------
 clients/window.c        | 41 ++++++++++-------------------------------
 3 files changed, 24 insertions(+), 87 deletions(-)

diff --git a/clients/confine.c b/clients/confine.c
index c0d908fb..255236a3 100644
--- a/clients/confine.c
+++ b/clients/confine.c
@@ -33,8 +33,6 @@
 #include <cairo.h>
 #include <math.h>
 #include <assert.h>
-#include <sys/timerfd.h>
-#include <sys/epoll.h>
 #include <unistd.h>
 
 #include <linux/input.h>
@@ -64,8 +62,7 @@ struct confine {
 	int reset;
 
 	struct input *cursor_timeout_input;
-	int cursor_timeout_fd;
-	struct task cursor_timeout_task;
+	struct toytimer cursor_timeout;
 
 	bool pointer_confined;
 
@@ -347,14 +344,7 @@ button_handler(struct widget *widget,
 static void
 cursor_timeout_reset(struct confine *confine)
 {
-	const long cursor_timeout = 500;
-	struct itimerspec its;
-
-	its.it_interval.tv_sec = 0;
-	its.it_interval.tv_nsec = 0;
-	its.it_value.tv_sec = cursor_timeout / 1000;
-	its.it_value.tv_nsec = (cursor_timeout % 1000) * 1000 * 1000;
-	timerfd_settime(confine->cursor_timeout_fd, 0, &its, NULL);
+	toytimer_arm_once_usec(&confine->cursor_timeout, 500 * 1000);
 }
 
 static int
@@ -406,15 +396,10 @@ leave_handler(struct widget *widget,
 }
 
 static void
-cursor_timeout_func(struct task *task, uint32_t events)
+cursor_timeout_func(struct toytimer *tt)
 {
 	struct confine *confine =
-		container_of(task, struct confine, cursor_timeout_task);
-	uint64_t exp;
-
-	if (read(confine->cursor_timeout_fd, &exp, sizeof (uint64_t)) !=
-	    sizeof(uint64_t))
-		abort();
+		container_of(tt, struct confine, cursor_timeout);
 
 	input_set_pointer_image(confine->cursor_timeout_input,
 				CURSOR_LEFT_PTR);
@@ -461,12 +446,8 @@ confine_create(struct display *display)
 	confine->line.old_y = -1;
 	confine->reset = 0;
 
-	confine->cursor_timeout_fd =
-		timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
-	confine->cursor_timeout_task.run = cursor_timeout_func;
-	display_watch_fd(window_get_display(confine->window),
-			 confine->cursor_timeout_fd,
-			 EPOLLIN, &confine->cursor_timeout_task);
+	toytimer_init(&confine->cursor_timeout, CLOCK_MONOTONIC,
+		      display, cursor_timeout_func);
 
 	return confine;
 }
@@ -474,9 +455,7 @@ confine_create(struct display *display)
 static void
 confine_destroy(struct confine *confine)
 {
-	display_unwatch_fd(window_get_display(confine->window),
-			   confine->cursor_timeout_fd);
-	close(confine->cursor_timeout_fd);
+	toytimer_fini(&confine->cursor_timeout);
 	if (confine->buffer)
 		cairo_surface_destroy(confine->buffer);
 	widget_destroy(confine->widget);
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index cabe851f..6d19d029 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -34,8 +34,6 @@
 #include <math.h>
 #include <cairo.h>
 #include <sys/wait.h>
-#include <sys/timerfd.h>
-#include <sys/epoll.h>
 #include <linux/input.h>
 #include <libgen.h>
 #include <ctype.h>
@@ -148,8 +146,7 @@ struct panel_launcher {
 struct panel_clock {
 	struct widget *widget;
 	struct panel *panel;
-	struct task clock_task;
-	int clock_fd;
+	struct toytimer timer;
 	char *format_string;
 	time_t refresh_timer;
 };
@@ -365,14 +362,10 @@ panel_launcher_touch_up_handler(struct widget *widget, struct input *input,
 }
 
 static void
-clock_func(struct task *task, uint32_t events)
+clock_func(struct toytimer *tt)
 {
-	struct panel_clock *clock =
-		container_of(task, struct panel_clock, clock_task);
-	uint64_t exp;
+	struct panel_clock *clock = container_of(tt, struct panel_clock, timer);
 
-	if (read(clock->clock_fd, &exp, sizeof exp) != sizeof exp)
-		abort();
 	widget_schedule_redraw(clock->widget);
 }
 
@@ -423,10 +416,7 @@ clock_timer_reset(struct panel_clock *clock)
 	its.it_interval.tv_nsec = 0;
 	its.it_value.tv_sec = clock->refresh_timer;
 	its.it_value.tv_nsec = 0;
-	if (timerfd_settime(clock->clock_fd, 0, &its, NULL) < 0) {
-		fprintf(stderr, "could not set timerfd\n: %m");
-		return -1;
-	}
+	toytimer_arm(&clock->timer, &its);
 
 	return 0;
 }
@@ -435,9 +425,7 @@ static void
 panel_destroy_clock(struct panel_clock *clock)
 {
 	widget_destroy(clock->widget);
-
-	close(clock->clock_fd);
-
+	toytimer_fini(&clock->timer);
 	free(clock);
 }
 
@@ -445,18 +433,10 @@ static void
 panel_add_clock(struct panel *panel)
 {
 	struct panel_clock *clock;
-	int timerfd;
-
-	timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
-	if (timerfd < 0) {
-		fprintf(stderr, "could not create timerfd\n: %m");
-		return;
-	}
 
 	clock = xzalloc(sizeof *clock);
 	clock->panel = panel;
 	panel->clock = clock;
-	clock->clock_fd = timerfd;
 
 	switch (panel->clock_format) {
 	case CLOCK_FORMAT_MINUTES:
@@ -471,9 +451,8 @@ panel_add_clock(struct panel *panel)
 		assert(!"not reached");
 	}
 
-	clock->clock_task.run = clock_func;
-	display_watch_fd(window_get_display(panel->window), clock->clock_fd,
-			 EPOLLIN, &clock->clock_task);
+	toytimer_init(&clock->timer, CLOCK_MONOTONIC,
+		      window_get_display(panel->window), clock_func);
 	clock_timer_reset(clock);
 
 	clock->widget = widget_add_widget(panel->widget, clock);
diff --git a/clients/window.c b/clients/window.c
index e1c9de71..d0c7581d 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -388,8 +388,7 @@ struct input {
 	int32_t repeat_delay_sec;
 	int32_t repeat_delay_nsec;
 
-	struct task repeat_task;
-	int repeat_timer_fd;
+	struct toytimer repeat_timer;
 	uint32_t repeat_sym;
 	uint32_t repeat_key;
 	uint32_t repeat_time;
@@ -2910,13 +2909,8 @@ static void
 input_remove_keyboard_focus(struct input *input)
 {
 	struct window *window = input->keyboard_focus;
-	struct itimerspec its;
 
-	its.it_interval.tv_sec = 0;
-	its.it_interval.tv_nsec = 0;
-	its.it_value.tv_sec = 0;
-	its.it_value.tv_nsec = 0;
-	timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
+	toytimer_disarm(&input->repeat_timer);
 
 	if (!window)
 		return;
@@ -2929,18 +2923,10 @@ input_remove_keyboard_focus(struct input *input)
 }
 
 static void
-keyboard_repeat_func(struct task *task, uint32_t events)
+keyboard_repeat_func(struct toytimer *tt)
 {
-	struct input *input =
-		container_of(task, struct input, repeat_task);
+	struct input *input = container_of(tt, struct input, repeat_timer);
 	struct window *window = input->keyboard_focus;
-	uint64_t exp;
-
-	if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp)
-		/* If we change the timer between the fd becoming
-		 * readable and getting here, there'll be nothing to
-		 * read and we get EAGAIN. */
-		return;
 
 	if (window && window->key_handler) {
 		(*window->key_handler)(window, input, input->repeat_time,
@@ -3163,11 +3149,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
 
 	if (state == WL_KEYBOARD_KEY_STATE_RELEASED &&
 	    key == input->repeat_key) {
-		its.it_interval.tv_sec = 0;
-		its.it_interval.tv_nsec = 0;
-		its.it_value.tv_sec = 0;
-		its.it_value.tv_nsec = 0;
-		timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
+		toytimer_disarm(&input->repeat_timer);
 	} else if (state == WL_KEYBOARD_KEY_STATE_PRESSED &&
 		   xkb_keymap_key_repeats(input->xkb.keymap, code)) {
 		input->repeat_sym = sym;
@@ -3177,7 +3159,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
 		its.it_interval.tv_nsec = input->repeat_rate_nsec;
 		its.it_value.tv_sec = input->repeat_delay_sec;
 		its.it_value.tv_nsec = input->repeat_delay_nsec;
-		timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
+		toytimer_arm(&input->repeat_timer, &its);
 	}
 }
 
@@ -5846,13 +5828,10 @@ display_add_input(struct display *d, uint32_t id, int display_seat_version)
 
 	toytimer_init(&input->cursor_timer, CLOCK_MONOTONIC, d,
 		      cursor_timer_func);
-	set_repeat_info(input, 40, 400);
 
-	input->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC,
-						TFD_CLOEXEC | TFD_NONBLOCK);
-	input->repeat_task.run = keyboard_repeat_func;
-	display_watch_fd(d, input->repeat_timer_fd,
-			 EPOLLIN, &input->repeat_task);
+	set_repeat_info(input, 40, 400);
+	toytimer_init(&input->repeat_timer, CLOCK_MONOTONIC, d,
+		      keyboard_repeat_func);
 }
 
 static void
@@ -5895,7 +5874,7 @@ input_destroy(struct input *input)
 
 	wl_list_remove(&input->link);
 	wl_seat_destroy(input->seat);
-	close(input->repeat_timer_fd);
+	toytimer_fini(&input->repeat_timer);
 	toytimer_fini(&input->cursor_timer);
 	free(input);
 }
-- 
2.16.1



More information about the wayland-devel mailing list