diff options
author | Oldřich Jedlička <oldium.pro@seznam.cz> | 2010-01-17 17:59:03 +0100 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2010-02-05 08:18:15 +1000 |
commit | 219a0d8fb54f179c7ac8d5953585849ab65a778b (patch) | |
tree | e17846859929b7a2fee7fea25eaaeba8e3ac87db | |
parent | a6a4c20121301905399c4e1c23980993bcbf2152 (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.c | 44 |
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); |