Fixed a race condition and resulting deadlock I introduced, which

resulted in the keyboard not working (at least on my Lenovo/IBM T60).
The device control thread could become aware of a dead device
at the time another thread (for example the add-on manager thread)
is already waiting for it. Then it tried to remove the device and
got stuck on locks that the other thread already holds (InputDeviceItem
list lock). Now the control threads check the "active" flag before
trying to remove the devices themselves, which, when set, is a sure
sign that the devices are already being removed and they don't need
to take care of it.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28342 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-10-27 11:28:25 +00:00
parent 0d2fb32f12
commit 9dd2d40e39
2 changed files with 22 additions and 6 deletions
@@ -379,8 +379,8 @@ KeyboardInputDevice::KeyboardInputDevice()
{
CALLED();
_RecursiveScan(kKeyboardDevicesDirectory);
StartMonitoringDevice(kKeyboardDevicesDirectory);
_RecursiveScan(kKeyboardDevicesDirectory);
}
@@ -618,8 +618,16 @@ KeyboardInputDevice::_DeviceWatcher(void* arg)
while (device->active) {
if (ioctl(device->fd, KB_READ, &buffer) != B_OK) {
device->device_watcher = -1;
device->owner->_RemoveDevice(device->path);
if (device->active) {
device->device_watcher = -1;
device->owner->_RemoveDevice(device->path);
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
// TOAST!
return 0;
}
@@ -234,8 +234,16 @@ MouseDevice::_Run()
memset(&movements, 0, sizeof(movements));
if (ioctl(fDevice, MS_READ, &movements) != B_OK) {
fThread = -1;
fTarget._RemoveDevice(fPath.String());
if (fActive) {
fThread = -1;
fTarget._RemoveDevice(fPath.String());
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
// TOAST!
return;
}
@@ -410,8 +418,8 @@ MouseInputDevice::MouseInputDevice()
{
CALLED();
_RecursiveScan(kMouseDevicesDirectory);
StartMonitoringDevice(kMouseDevicesDirectory);
_RecursiveScan(kMouseDevicesDirectory);
}