From f0756793e4c30278164d7a5cc483ce6a311c58dc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 31 May 2016 09:14:17 -0700 Subject: [PATCH] os: Lock input while messing with input device list The list of input devices may be changed by hotplugging while the server is active, and those changes may come from either the main thread or the input thread. That means the list of input devices needs to be protected by a mutex. This prevents input drivers from receiving I/O ready callbacks after removing a device. Signed-off-by: Keith Packard Reviewed-by: Peter Hutterer --- os/inputthread.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/os/inputthread.c b/os/inputthread.c index 390b66bf9..40a044375 100644 --- a/os/inputthread.c +++ b/os/inputthread.c @@ -197,12 +197,14 @@ InputThreadRegisterDev(int fd, dev->readInputProc = readInputProc; dev->readInputArgs = readInputArgs; + input_lock(); xorg_list_add(&dev->node, &inputThreadInfo->devs); FD_SET(fd, &inputThreadInfo->fds); InputThreadFillPipe(hotplugPipeWrite); DebugF("input-thread: registered device %d\n", fd); + input_unlock(); return 1; } @@ -228,6 +230,7 @@ InputThreadUnregisterDev(int fd) return 1; } + input_lock(); xorg_list_for_each_entry(dev, &inputThreadInfo->devs, node) if (dev->fd == fd) { found_device = TRUE; @@ -235,12 +238,17 @@ InputThreadUnregisterDev(int fd) } /* fd didn't match any registered device. */ - if (!found_device) + if (!found_device) { + input_unlock(); return 0; + } xorg_list_del(&dev->node); FD_CLR(fd, &inputThreadInfo->fds); + + input_unlock(); + free(dev); InputThreadFillPipe(hotplugPipeWrite); @@ -292,14 +300,14 @@ InputThreadDoWork(void *arg) DebugF("input-thread: %s generating events\n", __func__); + input_lock(); /* Call the device drivers to generate input events for us */ xorg_list_for_each_entry_safe(dev, next, &inputThreadInfo->devs, node) { if (FD_ISSET(dev->fd, &readyFds) && dev->readInputProc) { - input_lock(); dev->readInputProc(dev->fd, X_NOTIFY_READ, dev->readInputArgs); - input_unlock(); } } + input_unlock(); /* Kick main thread to process the generated input events and drain * events from hotplug pipe */