This explains the heisenbugs when running the test suite. libevdev gives us the syspath to the /sys/.../input123 node, not the one for the event node. The device node path is created based on the sysfs tree, so there's a window where the device node may not exist yet but we already returned the device node path.
In litest, we're using a udev monitor to wait until the device is ready for us, but the path interface only takes a device node path. So what happens is: * libevdev gives us a syspath for the input node and a device path * the monitor receives the input node udev device and matches the syspath * we pass that up to the caller litest_add_device_with_overrides() which opens the device node and adds it to libinput * the path interface creates a udev device from the device node, which still points to the old device node. Things fail because we don't have the device we expect or it doesn't send events and eventually times out [1]. The errors triggered by this are either odd udev property mismatches or timeouts because events are never processed. This race is fixed by simply constructing the actual device node path we expect from the udev device and waiting for the right device. [1] We rely on the caller to notify us when to remove the device and thus silently ignore ENODEV. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- test/litest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/litest.c b/test/litest.c index a099e1fe..9fc12354 100644 --- a/test/litest.c +++ b/test/litest.c @@ -2721,6 +2721,7 @@ litest_create_uinput_device_from_description(const char *name, { struct libevdev_uinput *uinput; const char *syspath; + char path[PATH_MAX]; struct udev *udev; struct udev_monitor *udev_monitor; @@ -2744,6 +2745,7 @@ litest_create_uinput_device_from_description(const char *name, uinput = litest_create_uinput(name, id, abs_info, events); syspath = libevdev_uinput_get_syspath(uinput); + snprintf(path, sizeof(path), "%s/event", syspath); /* blocking, we don't want to continue until udev is ready */ while (1) { @@ -2756,7 +2758,7 @@ litest_create_uinput_device_from_description(const char *name, } udev_syspath = udev_device_get_syspath(udev_device); - if (udev_syspath && streq(udev_syspath, syspath)) + if (udev_syspath && strneq(udev_syspath, path, strlen(path))) break; udev_device_unref(udev_device); -- 2.13.0 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel