mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-06 07:10:11 +01:00
test: use a udev monitor to wait for a device to disappear
Reduces potential race conditions. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
fb8a5b040a
commit
2857cfe87d
1 changed files with 75 additions and 32 deletions
107
test/litest.c
107
test/litest.c
|
|
@ -1447,12 +1447,79 @@ litest_create_device(enum litest_device_type which)
|
|||
return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct udev_monitor *
|
||||
udev_setup_monitor(void)
|
||||
{
|
||||
struct udev *udev;
|
||||
struct udev_monitor *udev_monitor;
|
||||
int rc;
|
||||
|
||||
udev = udev_new();
|
||||
litest_assert_notnull(udev);
|
||||
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
litest_assert_notnull(udev_monitor);
|
||||
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input",
|
||||
NULL);
|
||||
|
||||
|
||||
/* remove O_NONBLOCK */
|
||||
rc = fcntl(udev_monitor_get_fd(udev_monitor), F_SETFL, 0);
|
||||
litest_assert_int_ne(rc, -1);
|
||||
litest_assert_int_eq(udev_monitor_enable_receiving(udev_monitor),
|
||||
0);
|
||||
udev_unref(udev);
|
||||
|
||||
return udev_monitor;
|
||||
}
|
||||
|
||||
static struct udev_device *
|
||||
udev_wait_for_device_event(struct udev_monitor *udev_monitor,
|
||||
const char *udev_event,
|
||||
const char *syspath)
|
||||
{
|
||||
struct udev_device *udev_device = NULL;
|
||||
|
||||
/* blocking, we don't want to continue until udev is ready */
|
||||
while (1) {
|
||||
const char *udev_syspath = NULL;
|
||||
const char *udev_action;
|
||||
|
||||
udev_device = udev_monitor_receive_device(udev_monitor);
|
||||
litest_assert_notnull(udev_device);
|
||||
udev_action = udev_device_get_action(udev_device);
|
||||
if (!streq(udev_action, udev_event)) {
|
||||
udev_device_unref(udev_device);
|
||||
continue;
|
||||
}
|
||||
|
||||
udev_syspath = udev_device_get_syspath(udev_device);
|
||||
if (udev_syspath && strneq(udev_syspath,
|
||||
syspath,
|
||||
strlen(syspath)))
|
||||
break;
|
||||
|
||||
udev_device_unref(udev_device);
|
||||
}
|
||||
|
||||
return udev_device;
|
||||
}
|
||||
|
||||
void
|
||||
litest_delete_device(struct litest_device *d)
|
||||
{
|
||||
|
||||
struct udev_monitor *udev_monitor;
|
||||
struct udev_device *udev_device;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
udev_monitor = udev_setup_monitor();
|
||||
snprintf(path, sizeof(path),
|
||||
"%s/event",
|
||||
libevdev_uinput_get_syspath(d->uinput));
|
||||
|
||||
litest_assert_int_eq(d->skip_ev_syn, 0);
|
||||
|
||||
if (d->libinput_device) {
|
||||
|
|
@ -1467,6 +1534,12 @@ litest_delete_device(struct litest_device *d)
|
|||
free(d->private);
|
||||
memset(d,0, sizeof(*d));
|
||||
free(d);
|
||||
|
||||
udev_device = udev_wait_for_device_event(udev_monitor,
|
||||
"remove",
|
||||
path);
|
||||
udev_device_unref(udev_device);
|
||||
udev_monitor_unref(udev_monitor);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2763,52 +2836,22 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
const char *syspath;
|
||||
char path[PATH_MAX];
|
||||
|
||||
struct udev *udev;
|
||||
struct udev_monitor *udev_monitor;
|
||||
struct udev_device *udev_device;
|
||||
const char *udev_action;
|
||||
const char *udev_syspath = NULL;
|
||||
int rc;
|
||||
|
||||
udev = udev_new();
|
||||
litest_assert_notnull(udev);
|
||||
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
litest_assert_notnull(udev_monitor);
|
||||
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input",
|
||||
NULL);
|
||||
/* remove O_NONBLOCK */
|
||||
rc = fcntl(udev_monitor_get_fd(udev_monitor), F_SETFL, 0);
|
||||
litest_assert_int_ne(rc, -1);
|
||||
litest_assert_int_eq(udev_monitor_enable_receiving(udev_monitor),
|
||||
0);
|
||||
udev_monitor = udev_setup_monitor();
|
||||
|
||||
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) {
|
||||
udev_device = udev_monitor_receive_device(udev_monitor);
|
||||
litest_assert_notnull(udev_device);
|
||||
udev_action = udev_device_get_action(udev_device);
|
||||
if (!streq(udev_action, "add")) {
|
||||
udev_device_unref(udev_device);
|
||||
continue;
|
||||
}
|
||||
|
||||
udev_syspath = udev_device_get_syspath(udev_device);
|
||||
if (udev_syspath && strneq(udev_syspath, path, strlen(path)))
|
||||
break;
|
||||
|
||||
udev_device_unref(udev_device);
|
||||
}
|
||||
udev_device = udev_wait_for_device_event(udev_monitor, "add", path);
|
||||
|
||||
litest_assert(udev_device_get_property_value(udev_device, "ID_INPUT"));
|
||||
|
||||
udev_device_unref(udev_device);
|
||||
udev_monitor_unref(udev_monitor);
|
||||
udev_unref(udev);
|
||||
|
||||
return uinput;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue