Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent blocking when calling uvc_stop_streaming #59

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

hipersayanX
Copy link
Contributor

Applied the patches suggested by @saki4510t at issue #16.

Applied the patches suggested by @saki4510t at issue libuvc#16.
@@ -644,6 +675,11 @@ void LIBUSB_CALL _uvc_stream_callback(struct libusb_transfer *transfer) {

if ( strmh->running && resubmit )
libusb_submit_transfer(transfer);

if ( strmh->running && resubmit )
libusb_submit_transfer(transfer);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a duplicate of line 677.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, missed that.

if ( strmh->running && resubmit )
libusb_submit_transfer(transfer);
else
_uvc_delete_transfer(transfer);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems to be a copy of the code in the LIBUSB_TRANSFER_CANCELLED / LIBUSB_TRANSFER_ERROR / LIBUSB_TRANSFER_NO_DEVICE case of the switch statement above. That code above can free the transfer, which means the first line of _uvc_delete_transfer, uvc_stream_handle_t *strmh = transfer->user_data;, will be accessing free'd memory.

free(strmh->transfers[i]->buffer);
libusb_free_transfer(strmh->transfers[i]);
strmh->transfers[i] = NULL;
}
}*/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting out the error handling looks wrong.

@hipersayanX
Copy link
Contributor Author

I need to study the code a little bit more. I'm interested in having this issue fixed.

@hipersayanX
Copy link
Contributor Author

Ok, I've figured it out. transfer->status was LIBUSB_TRANSFER_COMPLETED when strmh->running == 0, so it was processing the packets instead of freeing it, those threads with transfer->status == LIBUSB_TRANSFER_COMPLETED && strmh->running == 0 were never called again, and therefore not being freed, causing the blocking.

So i just surrounded the LIBUSB_TRANSFER_COMPLETED block with if ( strmh->running ), so when not running it will go directly to the LIBUSB_TRANSFER_CANCELLED | LIBUSB_TRANSFER_ERROR | LIBUSB_TRANSFER_NO_DEVICE block and free the transfer.

@arkanoid87
Copy link

arkanoid87 commented May 5, 2018

This patch is not solving the problem on Android
I am still experiencing the hang on uvc_stop_streaming(...) and the kernelpanic when I unplug the usb camera without a clean release

UPDATE: I've also tried the uvc_stream_start + uvc_stream_get_frame path without using the callback, but it hangs on uvc_stream_stop occasionally

} else {
/* This is an isochronous mode transfer, so each packet has a payload transfer */
int packet_id;
if ( strmh->running ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding this if-test and then indenting the following logic, you could instead just make this if !strmh->running break; (which will also solve the merge conflict I believe.)

@maxrd2
Copy link
Contributor

maxrd2 commented Nov 20, 2020

Commit 4b6aa9f (was part of #110 not sure where it ended up) solves deadlock/double-free on android during uvc_stop_streaming() for me. Cleaned up patch can be found here: icona-swlab@268ae9d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants