[PATCH libinput 2/2] path: make sure udev devices are initialized before usage

Peter Hutterer peter.hutterer at who-t.net
Mon Feb 2 20:59:37 PST 2015


When creating uinput devices, we get the devnode from the kernel directly
rather than through udev. When we add this to the path backend too quickly the
udev_device we get may not be fully initialized and properties may be missing.
This causes false test results.

Avoid this by making sure the handle we have is initialized. This should never
trigger on a real device anyway, even creating a device through litest is slow
enough to avoid this issue. Only affected are the tests in misc.c where we
create the uinput device directly.

Nonetheless, handle this for the generic case so we don't run into heisenbugs
later.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/path.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/path.c b/src/path.c
index dd70efc..832a1fd 100644
--- a/src/path.c
+++ b/src/path.c
@@ -291,14 +291,34 @@ libinput_path_create_context(const struct libinput_interface *interface,
 }
 
 static inline struct udev_device *
-udev_device_from_devnode(struct udev *udev, const char *devnode)
+udev_device_from_devnode(struct libinput *libinput,
+			 struct udev *udev,
+			 const char *devnode)
 {
+	struct udev_device *dev;
 	struct stat st;
+	size_t count = 0;
 
 	if (stat(devnode, &st) < 0)
 		return NULL;
 
-	return udev_device_new_from_devnum(udev, 'c', st.st_rdev);
+	dev = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
+
+	while (dev && !udev_device_get_is_initialized(dev)) {
+		udev_device_unref(dev);
+		msleep(10);
+		dev = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
+
+		count++;
+		if (count > 10) {
+			log_bug_libinput(libinput,
+					"udev device never initialized (%s)\n",
+					devnode);
+			break;
+		}
+	}
+
+	return dev;
 }
 
 LIBINPUT_EXPORT struct libinput_device *
@@ -315,7 +335,7 @@ libinput_path_add_device(struct libinput *libinput,
 		return NULL;
 	}
 
-	udev_device = udev_device_from_devnode(udev, path);
+	udev_device = udev_device_from_devnode(libinput, udev, path);
 	if (!udev_device) {
 		log_bug_client(libinput, "Invalid path %s\n", path);
 		return NULL;
-- 
2.1.0



More information about the wayland-devel mailing list