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>
This commit is contained in:
parent
b91cec26de
commit
08b22c7faf
|
@ -876,6 +876,36 @@ CloseDevice(DeviceIntPtr dev)
|
||||||
xfree(dev);
|
xfree(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.
|
* Shut down all devices, free all resources, etc.
|
||||||
* Only useful if you're shutting down the server!
|
* Only useful if you're shutting down the server!
|
||||||
|
@ -883,7 +913,7 @@ CloseDevice(DeviceIntPtr dev)
|
||||||
void
|
void
|
||||||
CloseDownDevices(void)
|
CloseDownDevices(void)
|
||||||
{
|
{
|
||||||
DeviceIntPtr dev, next;
|
DeviceIntPtr dev;
|
||||||
|
|
||||||
/* Float all SDs before closing them. Note that at this point resources
|
/* 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
|
* (e.g. cursors) have been freed already, so we can't just call
|
||||||
|
@ -896,16 +926,8 @@ CloseDownDevices(void)
|
||||||
dev->u.master = NULL;
|
dev->u.master = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (dev = inputInfo.devices; dev; dev = next)
|
CloseDeviceList(&inputInfo.devices);
|
||||||
{
|
CloseDeviceList(&inputInfo.off_devices);
|
||||||
next = dev->next;
|
|
||||||
DeleteInputDeviceRequest(dev);
|
|
||||||
}
|
|
||||||
for (dev = inputInfo.off_devices; dev; dev = next)
|
|
||||||
{
|
|
||||||
next = dev->next;
|
|
||||||
DeleteInputDeviceRequest(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseDevice(inputInfo.pointer);
|
CloseDevice(inputInfo.pointer);
|
||||||
CloseDevice(inputInfo.keyboard);
|
CloseDevice(inputInfo.keyboard);
|
||||||
|
|
Loading…
Reference in New Issue