* 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()
|
HIDDevice::Close()
|
||||||
{
|
{
|
||||||
fOpen = false;
|
fOpen = false;
|
||||||
|
// make threads waiting for a transfer bail out
|
||||||
|
if (fTransferNotifySem >= 0) {
|
||||||
|
delete_sem(fTransferNotifySem);
|
||||||
|
fTransferNotifySem = -1;
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static void _TransferCallback(void *cookie,
|
|||||||
|
|
||||||
char * fName;
|
char * fName;
|
||||||
int32 fParentCookie;
|
int32 fParentCookie;
|
||||||
bool fOpen;
|
volatile bool fOpen;
|
||||||
bool fRemoved;
|
bool fRemoved;
|
||||||
|
|
||||||
struct ring_buffer * fRingBuffer;
|
struct ring_buffer * fRingBuffer;
|
||||||
|
|||||||
@@ -65,15 +65,15 @@ KeyboardDevice::Control(uint32 op, void *buffer, size_t length)
|
|||||||
_SetTransferProcessed();
|
_SetTransferProcessed();
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
} else if (result == B_TIMED_OUT) {
|
} else if (result == B_TIMED_OUT && IsOpen()) {
|
||||||
// this case is for handling key repeats, it means
|
// this case is for handling key repeats, it means
|
||||||
// no interrupt transfer has happened
|
// no interrupt transfer has happened
|
||||||
_WriteKey(fCurrentRepeatKey, true);
|
_WriteKey(fCurrentRepeatKey, true);
|
||||||
// the next timeout is reduced to the repeat_rate
|
// the next timeout is reduced to the repeat_rate
|
||||||
fCurrentRepeatDelay = fRepeatRate;
|
fCurrentRepeatDelay = fRepeatRate;
|
||||||
} else if (result == B_INTERRUPTED)
|
} else if (result == B_INTERRUPTED && IsOpen()) {
|
||||||
continue;
|
continue;
|
||||||
else if (result != B_OK)
|
} else
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user