Commit a790ff35 authored by Peter Hutterer's avatar Peter Hutterer

Swap the registered input device on DEVICE_OFF when needed

If we don't swap out the pInfo previously passed to xf86AddEnabledDevice(),
the thread eventually calls read_input on a struct that has been deleted.
Avoid this by swapping out the to-be-destroyed pInfo with the first one we

Reproducer: sudo udevadm trigger --type=devices --action=add
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <>
Reviewed-by: default avatarHans de Goede <>
parent 6318ac42
......@@ -87,6 +87,7 @@
struct xf86libinput_driver {
struct libinput *libinput;
int device_enabled_count;
void *registered_InputInfoPtr;
static struct xf86libinput_driver driver_context;
......@@ -583,6 +584,7 @@ xf86libinput_on(DeviceIntPtr dev)
if (driver_context.device_enabled_count == 0) {
driver_context.registered_InputInfoPtr = pInfo;
/* Can't use xf86AddEnabledDevice on an epollfd */
......@@ -1131,6 +1133,39 @@ xf86libinput_init(DeviceIntPtr dev)
return 0;
static bool
is_libinput_device(InputInfoPtr pInfo)
char *driver;
BOOL rc;
driver = xf86CheckStrOption(pInfo->options, "driver", "");
rc = strcmp(driver, "libinput") == 0;
return rc;
static void
swap_registered_device(InputInfoPtr pInfo)
InputInfoPtr next;
if (pInfo != driver_context.registered_InputInfoPtr)
next = xf86FirstLocalDevice();
while (next == pInfo || !is_libinput_device(next))
next = next->next;
if (next) /* shouldn't ever be NULL anyway */
driver_context.registered_InputInfoPtr = next;
static void
xf86libinput_destroy(DeviceIntPtr dev)
......@@ -1138,6 +1173,17 @@ xf86libinput_destroy(DeviceIntPtr dev)
struct xf86libinput *driver_data = pInfo->private;
struct xf86libinput_device *shared_device = driver_data->shared_device;
/* If the device being destroyed is the one we used for
* xf86AddEnabledDevice(), we need to swap it out for one that is
* still live. xf86AddEnabledDevice() buffers some data and once the
* deletes pInfo (when DEVICE_OFF completes) the thread will keep
* calling that struct's read_input because we never removed it.
* Avoid this by removing ours and substituting one that's still
* valid, the fd is the same anyway (libinput's epollfd).
if (driver_context.device_enabled_count > 0)
if (driver_data->tablet_tool)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment