summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOldřich Jedlička <oldium.pro@seznam.cz>2010-01-17 17:59:03 +0100
committerPeter Hutterer <peter.hutterer@who-t.net>2010-02-05 08:18:15 +1000
commit219a0d8fb54f179c7ac8d5953585849ab65a778b (patch)
treee17846859929b7a2fee7fea25eaaeba8e3ac87db
parenta6a4c20121301905399c4e1c23980993bcbf2152 (diff)
Allow driver to call DeleteInputDeviceRequest during UnInit
When the input driver (like xf86-input-wacom) removes it's devices during a call to UnInit, the CloseDownDevices() cannot handle it. The "next" variable can become a pointer to freed memory. The patch introduces order-independent device freeing mechanism by remembering the already freed device ids. The devices can reorder any time during freeing. No device will be double-freed - if the removing failed for any reason; some implementations of DeleteInputDeviceRequest don't free the devices already. Signed-off-by: Oldřich Jedlička <oldium.pro@seznam.cz> Reviewed-by: Simon Thum <simon.thum@gmx.de> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> (cherry picked from commit 08b22c7faf97217ea4d497eec6624fc3dd916d9b)
-rw-r--r--dix/devices.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/dix/devices.c b/dix/devices.c
index 245a95b0f..ef199b785 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -878,13 +878,43 @@ CloseDevice(DeviceIntPtr dev)
}
/**
+ * Shut down all devices of one list and free all resources.
+ */
+static
+void
+CloseDeviceList(DeviceIntPtr *listHead)
+{
+ /* Used to mark devices that we tried to free */
+ Bool freedIds[MAXDEVICES];
+ DeviceIntPtr dev;
+ int i;
+
+ if (listHead == NULL)
+ return;
+
+ for (i = 0; i < MAXDEVICES; i++)
+ freedIds[i] = FALSE;
+
+ dev = *listHead;
+ while (dev != NULL)
+ {
+ freedIds[dev->id] = TRUE;
+ DeleteInputDeviceRequest(dev);
+
+ dev = *listHead;
+ while (dev != NULL && freedIds[dev->id])
+ dev = dev->next;
+ }
+}
+
+/**
* Shut down all devices, free all resources, etc.
* Only useful if you're shutting down the server!
*/
void
CloseDownDevices(void)
{
- DeviceIntPtr dev, next;
+ DeviceIntPtr dev;
/* Float all SDs before closing them. Note that at this point resources
* (e.g. cursors) have been freed already, so we can't just call
@@ -897,16 +927,8 @@ CloseDownDevices(void)
dev->u.master = NULL;
}
- for (dev = inputInfo.devices; dev; dev = next)
- {
- next = dev->next;
- DeleteInputDeviceRequest(dev);
- }
- for (dev = inputInfo.off_devices; dev; dev = next)
- {
- next = dev->next;
- DeleteInputDeviceRequest(dev);
- }
+ CloseDeviceList(&inputInfo.devices);
+ CloseDeviceList(&inputInfo.off_devices);
CloseDevice(inputInfo.pointer);
CloseDevice(inputInfo.keyboard);