USB: Change from an instant to an unlimited timeout in ControlPipe::SendRequest.

Otherwise we have a race (or worse): in the case where the transfer
has completed or is in the process of completion between CancelQueued
and here, the callback can still be invoked after we returned and
cause corruption.

Discovered while working on USB support in the FreeBSD compatibility
layer: a lock inversion problem meant these timeouts always occurred
but then the callback would be invoked later and corrupt stack.

With this change, such problems will instead cause deadlocks.
That's not an ideal situation to be in, but we should detect
such problems elsewhere and make them into asserts; deadlocks
are assuredly better than random memory corruption.
This commit is contained in:
Augustin Cavalier 2022-02-24 21:06:08 -05:00
parent 7c97a7846f
commit eeec7ed477

View File

@ -412,7 +412,7 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
// After the above cancel returns it is guaranteed that the callback // After the above cancel returns it is guaranteed that the callback
// has been invoked. Therefore we can simply grab that released // has been invoked. Therefore we can simply grab that released
// semaphore again to clean up. // semaphore again to clean up.
acquire_sem_etc(fNotifySem, 1, B_RELATIVE_TIMEOUT, 0); acquire_sem(fNotifySem);
if (actualLength) if (actualLength)
*actualLength = 0; *actualLength = 0;