[PATCH libinput 1/3] Add a timer subsystem
Peter Hutterer
peter.hutterer at who-t.net
Wed Jun 4 20:40:26 PDT 2014
On Wed, Jun 04, 2014 at 05:26:34PM +0200, Hans de Goede wrote:
> Currently we are using DIY timers in the touchpad softbutton and tap handling
> code, and at least the softbutton code gets its wrong. It uses one timer-fd
> per touchpad to set a timeout per touch, which means that if a timeout is
> set for 100ms from now for touch 1, and then a timeout gets set 50 ms later
> for 200 ms from now, then the timeout for touch 1 will come 150 ms too late.
>
> This commits adds a proper timer subsystem so that we've one place to deal
> with timer handling, and so that we can only get it wrong (well hopefully
> we get it right) in one place.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
[...]
> +static void
> +libinput_timer_handler(void *data)
> +{
> + struct libinput *libinput = data;
> + struct libinput_timer *timer, *tmp;
> + struct timespec ts;
> + uint64_t now;
> + int r;
> +
> + r = clock_gettime(CLOCK_MONOTONIC, &ts);
> + if (r) {
> + log_error("clock_gettime error: %s\n", strerror(errno));
> + return;
> + }
> +
> + now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
> +
> + list_for_each_safe(timer, tmp, &libinput->timer.list, list) {
> + if (timer->expire <= now) {
> + /* Clear the timer before calling timer_func,
> + as timer_func may re-arm it */
> + libinput_timer_cancel(timer);
> + timer->timer_func(now, timer->timer_func_data);
would it make sense to pass the timer itself into the timer func, for the
use-cases where the func handles multiple timers and only needs to e.g.
print and re-arm that timer?
this is an internal API so we can add it when needed later.
> + }
> + }
> +}
> +
> +int
> +libinput_timer_subsys_init(struct libinput *libinput)
> +{
> + libinput->timer.fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
> + if (libinput->timer.fd < 0)
> + return -1;
> +
> + list_init(&libinput->timer.list);
> +
> + libinput->timer.source = libinput_add_fd(libinput,
> + libinput->timer.fd,
> + libinput_timer_handler,
> + libinput);
> + if (!libinput->timer.source) {
> + close(libinput->timer.fd);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +void
> +libinput_timer_subsys_exit(struct libinput *libinput)
> +{
> + /* All timer uses should have destroyed their timers now */
typo: "users"
> +struct libinput_timer {
> + struct libinput *libinput;
> + struct list list;
> + uint64_t expire;
do me a favour and add a comment here and in
libinput_timer_set that this is in abstime, not reltime.
> + void (*timer_func)(uint64_t now, void *timer_func_data);
> + void *timer_func_data;
> +};
series:
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
with Jonas' comments and the above addressed.
two other things that you may or may not want to add because they help
debugging but require some more effort:
- put a log_bug_libinput() into libinput_timer_set if the timer is <
current time
- put a log_bug_libinput() into libinput_timer_set if the timer is
more than say 5s into the future. this is arbitrary but a
good safety guard that can save on some debugging time.
Cheers,
Peter
More information about the wayland-devel
mailing list