* When a device closes, delete the transfer semaphore, so that threads blocking

on it are unblocked and get an error.
* Make fOpen volatile to prevent unwanted caching effects when checking it from
  different threads. (?)
* Check IsOpen() in the KeyboardDevice class in more acquire_sem_etc() return
  cases, analogous to the MouseDevice class.

I am still getting a problem when relaunching input_server with the input_server
add-on thread that ioctl()s on a USB keyboard fd, which should have never fired
because it's a fake device from a KVM. After the first input_server instance is
gone, this thread keeps on busy looping in acquire_sem_etc()->switch_sem() from
within the ioctl() of the KeyboardDevice usb_hid driver. Still on it.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28350 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-10-27 16:52:39 +00:00
parent dae439fe60
commit dab68c33ed
3 changed files with 9 additions and 4 deletions
@@ -240,6 +240,11 @@ status_t
HIDDevice::Close()
{
fOpen = false;
// make threads waiting for a transfer bail out
if (fTransferNotifySem >= 0) {
delete_sem(fTransferNotifySem);
fTransferNotifySem = -1;
}
return B_OK;
}
@@ -78,7 +78,7 @@ static void _TransferCallback(void *cookie,
char * fName;
int32 fParentCookie;
bool fOpen;
volatile bool fOpen;
bool fRemoved;
struct ring_buffer * fRingBuffer;
@@ -65,15 +65,15 @@ KeyboardDevice::Control(uint32 op, void *buffer, size_t length)
_SetTransferProcessed();
if (result != B_OK)
return result;
} else if (result == B_TIMED_OUT) {
} else if (result == B_TIMED_OUT && IsOpen()) {
// this case is for handling key repeats, it means
// no interrupt transfer has happened
_WriteKey(fCurrentRepeatKey, true);
// the next timeout is reduced to the repeat_rate
fCurrentRepeatDelay = fRepeatRate;
} else if (result == B_INTERRUPTED)
} else if (result == B_INTERRUPTED && IsOpen()) {
continue;
else if (result != B_OK)
} else
return result;
}