libusb
libusb copied to clipboard
Provide a way to abort transfers in a synchronous, safe, and non-blocking way, and in general how to deal gracefully with closing a device while there are outstanding transfers
libusb_cancel_transfer() can stop the transfer, but still calls the completion callback.
There should be a way to stop them instantly (but still non-blocking), and allowing the application to do with the aborted libusb_transfer whatever it wants after the call, immediately, without having to wait for the callback.
This will make internal application logic simpler, which I think would benefit many users. I've wrote more about this in #700, but made a new issue, because the previous one was too hard to read.
That is the way it is handled even in kernel space likely for good reasons The app shall consider the xfer belong to lib when submitted It is easy to handle a lock ans à flag in app data related to the xfer and analyse it in callback and Just do nothing is that case.
That usually means an app which wants to stop transfers immediately (without having to block or wait) has to add an indirection. I do it like this: have a chain of 2 callbacks, where libusb_transfer.callback is the first callback. The first callback checks whether the app "abandoned" this transfer, and only if not, calls the second callback. If the transfers was "abandoned", the app-managed device refcount is decreased, and if it has reached 0, usb_close is called.
But that seems overly roundabout.
I am in favor of gracefully aborting all the outstanding transfers during libusb_close(), but the only safe thing to do is forget about the transfers entirely. Calling the callback, freeing the transfer buffer, and freeing the transfer itself are questionable at best in this scenario.
Getting more experience with using libusb, I think much of the evil issues is in libusb_transfer.callback. It seems to complicate a lot, both for users and libusb. A little bit of callback hell. But not sure how this could be improved.
Maybe it is good to have some documentation improvement in this aspect.
I am in favor of gracefully aborting all the outstanding transfers during
libusb_close(), but the only safe thing to do is forget about the transfers entirely. Calling the callback, freeing the transfer buffer, and freeing the transfer itself are questionable at best in this scenario.
Im struggling with a issue that an endpoint is dead when a usb device does not responded to the endpoint with libusb recently, that ep is not getting recovered even if the device is unplugged & plugged. I'm looking forward to find the resolution even if it's Hack the code.
that will be grateful if anyone put patch(es) here....
There should be a way to stop them instantly (but still non-blocking), and allowing the application to do with the aborted
libusb_transferwhatever it wants after the call, immediately
Is that even possible (even in theory)?
You could easily try to stop a transfer right in the middle of the callback. To avoid issues in this case, you either explicitly wait for complitioon or libusb would have to add internal locks/checks whith wouldn't make things any easier for libusb itself, and libusb_cancel_transfer() becomes a blocking call.
- https://github.com/libusb/libusb/issues/297#issuecomment-675762505 From Chris
Closing a device while there are outstanding transfers is 100% an application error. Handling this gracefully has been discussed in #540, #610 and #703.
So I have closed #297, #540 and #610 but keep #703. Edit: keeping #297 open as well.
https://libusb.sourceforge.io/api-1.0/libusb_io.html
The synchronous interface
...
Additionally, there is no opportunity to cancel the transfer after the request has been submitted.
Related issues:
- https://github.com/libusb/libusb/issues/703
- https://github.com/libusb/libusb/issues/182
- https://github.com/libusb/libusb/issues/297
- https://github.com/libusb/libusb/issues/540
- https://github.com/libusb/libusb/issues/610
I looked at the issue here and similar things were mentioned in the discussion. https://github.com/libusb/libusb/issues/1124
@hjelmn mentioned here.
- https://github.com/libusb/libusb/issues/1124#issuecomment-1096785615
Note also that ALL transfers MUST be freed before libusb_exit. This has always been the case but probably not well documented.
And here.
- https://github.com/libusb/libusb/issues/1124#issuecomment-1097016750
All libusb objects must be released before libusb_exit is called.
Wiki updated. https://github.com/libusb/libusb/wiki/FAQ#user-content-What_are_the_differences_between_Synchronous_and_asynchronous_device_IO
Please take note that ALL transfers MUST be freed before libusb_exit() is called.
Please take note that ALL libusb objects MUST be released before libusb_exit() is called.
Please also take note that there is no way to cancel Synchronous transfer after the request has been submitted.