[v2,libinput,1/2] evdev: Ensure the libevdev object receives the new fd on resume

Submitted by Peter Hutterer on Dec. 10, 2014, 1:47 a.m.

Details

Message ID 1418176056-3270-1-git-send-email-peter.hutterer@who-t.net
State Not Applicable
Headers show

Not browsing as part of any series.

Commit Message

Peter Hutterer Dec. 10, 2014, 1:47 a.m.
From: Carlos Garnacho <carlosg@gnome.org>

Otherwise, input_events will be attempted to read from the wrong place,
which also leaves the right/current fd with pending data to be read,
making the epoll fd wake up constantly.

Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
Changes to v1:
- sync libevdev's state after change_fd

 src/evdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Patch hide | download patch | download mbox

diff --git a/src/evdev.c b/src/evdev.c
index 0873c99..3f15560 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1985,6 +1985,8 @@  evdev_device_resume(struct evdev_device *device)
 	struct libinput *libinput = device->base.seat->libinput;
 	int fd;
 	const char *devnode;
+	struct input_event ev;
+	enum libevdev_read_status status;
 
 	if (device->fd != -1)
 		return 0;
@@ -2011,6 +2013,20 @@  evdev_device_resume(struct evdev_device *device)
 			return -ENODEV;
 	}
 
+	libevdev_change_fd(device->evdev, fd);
+	libevdev_set_clock_id(device->evdev, CLOCK_MONOTONIC);
+
+	/* re-sync libevdev's view of the device, but discard the actual
+	   events. Our device is in a neutral state already */
+	libevdev_next_event(device->evdev,
+			    LIBEVDEV_READ_FLAG_FORCE_SYNC,
+			    &ev);
+	do {
+		status = libevdev_next_event(device->evdev,
+					     LIBEVDEV_READ_FLAG_SYNC,
+					     &ev);
+	} while (status == LIBEVDEV_READ_STATUS_SYNC);
+
 	device->source =
 		libinput_add_fd(libinput, fd, evdev_device_dispatch, device);
 	if (!device->source) {

Comments

Hi,

On 10-12-14 02:47, Peter Hutterer wrote:
> From: Carlos Garnacho <carlosg@gnome.org>
>
> Otherwise, input_events will be attempted to read from the wrong place,
> which also leaves the right/current fd with pending data to be read,
> making the epoll fd wake up constantly.
>
> Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

Series looks good and is:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> ---
> Changes to v1:
> - sync libevdev's state after change_fd
>
>   src/evdev.c | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
>
> diff --git a/src/evdev.c b/src/evdev.c
> index 0873c99..3f15560 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1985,6 +1985,8 @@ evdev_device_resume(struct evdev_device *device)
>   	struct libinput *libinput = device->base.seat->libinput;
>   	int fd;
>   	const char *devnode;
> +	struct input_event ev;
> +	enum libevdev_read_status status;
>
>   	if (device->fd != -1)
>   		return 0;
> @@ -2011,6 +2013,20 @@ evdev_device_resume(struct evdev_device *device)
>   			return -ENODEV;
>   	}
>
> +	libevdev_change_fd(device->evdev, fd);
> +	libevdev_set_clock_id(device->evdev, CLOCK_MONOTONIC);
> +
> +	/* re-sync libevdev's view of the device, but discard the actual
> +	   events. Our device is in a neutral state already */
> +	libevdev_next_event(device->evdev,
> +			    LIBEVDEV_READ_FLAG_FORCE_SYNC,
> +			    &ev);
> +	do {
> +		status = libevdev_next_event(device->evdev,
> +					     LIBEVDEV_READ_FLAG_SYNC,
> +					     &ev);
> +	} while (status == LIBEVDEV_READ_STATUS_SYNC);
> +
>   	device->source =
>   		libinput_add_fd(libinput, fd, evdev_device_dispatch, device);
>   	if (!device->source) {
>