Hold input lock for deviceProc
This ensures that the deviceProc is never called while the input thread is processing data from the device. Signed-off-by: Keith Packard <keithp@keithp.com> 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
dfc91f0f63
commit
52d6a1e832
|
@ -399,9 +399,11 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input_lock();
|
||||||
if ((*prev != dev) || !dev->inited ||
|
if ((*prev != dev) || !dev->inited ||
|
||||||
((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) {
|
((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) {
|
||||||
ErrorF("[dix] couldn't enable device %d\n", dev->id);
|
ErrorF("[dix] couldn't enable device %d\n", dev->id);
|
||||||
|
input_unlock();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
dev->enabled = TRUE;
|
dev->enabled = TRUE;
|
||||||
|
@ -410,6 +412,7 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||||
for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next);
|
for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next);
|
||||||
*prev = dev;
|
*prev = dev;
|
||||||
dev->next = NULL;
|
dev->next = NULL;
|
||||||
|
input_unlock();
|
||||||
|
|
||||||
enabled = TRUE;
|
enabled = TRUE;
|
||||||
XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
|
XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
|
||||||
|
@ -488,20 +491,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||||
if (dev->spriteInfo->paired)
|
if (dev->spriteInfo->paired)
|
||||||
dev->spriteInfo->paired = NULL;
|
dev->spriteInfo->paired = NULL;
|
||||||
|
|
||||||
|
input_lock();
|
||||||
(void) (*dev->deviceProc) (dev, DEVICE_OFF);
|
(void) (*dev->deviceProc) (dev, DEVICE_OFF);
|
||||||
dev->enabled = FALSE;
|
dev->enabled = FALSE;
|
||||||
|
|
||||||
FreeSprite(dev);
|
|
||||||
|
|
||||||
/* now that the device is disabled, we can reset the event reader's
|
/* now that the device is disabled, we can reset the event reader's
|
||||||
* last.slave */
|
* last.slave */
|
||||||
input_lock();
|
|
||||||
for (other = inputInfo.devices; other; other = other->next) {
|
for (other = inputInfo.devices; other; other = other->next) {
|
||||||
if (other->last.slave == dev)
|
if (other->last.slave == dev)
|
||||||
other->last.slave = NULL;
|
other->last.slave = NULL;
|
||||||
}
|
}
|
||||||
input_unlock();
|
input_unlock();
|
||||||
|
|
||||||
|
FreeSprite(dev);
|
||||||
|
|
||||||
LeaveWindow(dev);
|
LeaveWindow(dev);
|
||||||
SetFocusOut(dev);
|
SetFocusOut(dev);
|
||||||
|
|
||||||
|
@ -569,7 +572,9 @@ ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||||
if (!dev || !dev->deviceProc)
|
if (!dev || !dev->deviceProc)
|
||||||
return BadImplementation;
|
return BadImplementation;
|
||||||
|
|
||||||
|
input_lock();
|
||||||
ret = (*dev->deviceProc) (dev, DEVICE_INIT);
|
ret = (*dev->deviceProc) (dev, DEVICE_INIT);
|
||||||
|
input_unlock();
|
||||||
dev->inited = (ret == Success);
|
dev->inited = (ret == Success);
|
||||||
if (!dev->inited)
|
if (!dev->inited)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -935,6 +940,8 @@ FreeAllDeviceClasses(ClassesPtr classes)
|
||||||
* enable it again and free associated structs. If you want the device to just
|
* enable it again and free associated structs. If you want the device to just
|
||||||
* be disabled, DisableDevice().
|
* be disabled, DisableDevice().
|
||||||
* Don't call this function directly, use RemoveDevice() instead.
|
* Don't call this function directly, use RemoveDevice() instead.
|
||||||
|
*
|
||||||
|
* Called with input lock held.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CloseDevice(DeviceIntPtr dev)
|
CloseDevice(DeviceIntPtr dev)
|
||||||
|
@ -1071,6 +1078,11 @@ void
|
||||||
AbortDevices(void)
|
AbortDevices(void)
|
||||||
{
|
{
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
|
|
||||||
|
/* Do not call input_lock as we don't know what
|
||||||
|
* state the input thread might be in, and that could
|
||||||
|
* cause a dead-lock.
|
||||||
|
*/
|
||||||
nt_list_for_each_entry(dev, inputInfo.devices, next) {
|
nt_list_for_each_entry(dev, inputInfo.devices, next) {
|
||||||
if (!IsMaster(dev))
|
if (!IsMaster(dev))
|
||||||
(*dev->deviceProc) (dev, DEVICE_ABORT);
|
(*dev->deviceProc) (dev, DEVICE_ABORT);
|
||||||
|
@ -1135,6 +1147,8 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||||
flags[dev->id] = XIDeviceDisabled;
|
flags[dev->id] = XIDeviceDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input_lock();
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
|
for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
|
||||||
next = tmp->next;
|
next = tmp->next;
|
||||||
|
@ -1167,6 +1181,8 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input_unlock();
|
||||||
|
|
||||||
if (ret == Success && initialized) {
|
if (ret == Success && initialized) {
|
||||||
inputInfo.numDevices--;
|
inputInfo.numDevices--;
|
||||||
SendDevicePresenceEvent(deviceid, DeviceRemoved);
|
SendDevicePresenceEvent(deviceid, DeviceRemoved);
|
||||||
|
|
Loading…
Reference in New Issue