* 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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user