From 9dd2d40e390a95d522ac9074ac9d0e46b894cab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 27 Oct 2008 11:28:25 +0000 Subject: [PATCH] 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 --- .../devices/keyboard/KeyboardInputDevice.cpp | 14 +++++++++++--- .../devices/mouse/MouseInputDevice.cpp | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp b/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp index 4811d4a1b9..5adde5b699 100644 --- a/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp +++ b/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp @@ -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; } diff --git a/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp b/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp index 8d2ac4d645..2868b28af3 100644 --- a/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp +++ b/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp @@ -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); }