USB: Make Pipe::CancelQueuedTransfers virtual and add a ControlPipe variant.
Control pipes have internal structures to wait for queued requests. When force-cancelling queued transfers, the callbacks will not be called, and so such transfers would be left hanging until the timeout occurred or the destructor destroys the semaphore and mutex. This probably will not fix any hang-related tickets, though, as force cancellation is pretty much only used during device/pipe teardown. Change-Id: I41db7caf380cdd082bc3509e95262317489bf100 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4488 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
3e0eea85ec
commit
2f496b3095
@ -23,7 +23,7 @@ Pipe::~Pipe()
|
||||
{
|
||||
PutUSBID();
|
||||
|
||||
CancelQueuedTransfers(true);
|
||||
Pipe::CancelQueuedTransfers(true);
|
||||
GetBusManager()->NotifyPipeChange(this, USB_CHANGE_DESTROYED);
|
||||
}
|
||||
|
||||
@ -334,6 +334,10 @@ ControlPipe::ControlPipe(Object *parent)
|
||||
|
||||
ControlPipe::~ControlPipe()
|
||||
{
|
||||
// We do this here in case a submitted request is still running.
|
||||
PutUSBID();
|
||||
ControlPipe::CancelQueuedTransfers(true);
|
||||
|
||||
if (fNotifySem >= 0)
|
||||
delete_sem(fNotifySem);
|
||||
mutex_lock(&fSendRequestLock);
|
||||
@ -465,3 +469,18 @@ ControlPipe::QueueRequest(uint8 requestType, uint8 request, uint16 value,
|
||||
delete transfer;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ControlPipe::CancelQueuedTransfers(bool force)
|
||||
{
|
||||
if (force && fNotifySem >= 0) {
|
||||
// There is likely a transfer currently running; we need to cancel it
|
||||
// manually, as callbacks are not invoked when force-cancelling.
|
||||
fTransferStatus = B_CANCELED;
|
||||
fActualLength = 0;
|
||||
release_sem_etc(fNotifySem, 1, B_RELEASE_IF_WAITING_ONLY);
|
||||
}
|
||||
|
||||
return Pipe::CancelQueuedTransfers(force);
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ virtual void SetDataToggle(bool toggle)
|
||||
{ fDataToggle = toggle; }
|
||||
|
||||
status_t SubmitTransfer(Transfer *transfer);
|
||||
status_t CancelQueuedTransfers(bool force);
|
||||
virtual status_t CancelQueuedTransfers(bool force);
|
||||
|
||||
void SetControllerCookie(void *cookie)
|
||||
{ fControllerCookie = cookie; }
|
||||
@ -414,6 +414,8 @@ static void SendRequestCallback(void *cookie,
|
||||
usb_callback_func callback,
|
||||
void *callbackCookie);
|
||||
|
||||
virtual status_t CancelQueuedTransfers(bool force);
|
||||
|
||||
private:
|
||||
mutex fSendRequestLock;
|
||||
sem_id fNotifySem;
|
||||
|
Loading…
Reference in New Issue
Block a user