From 1b2aa976d8a34e7df05a55cde414b2b00d338bc6 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Wed, 23 Nov 2016 23:15:02 +0100 Subject: [PATCH] libusb: properly cancel outstanding transfers --- platform/libusb/hci_transport_h2_libusb.c | 84 ++++++++++++++++------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/platform/libusb/hci_transport_h2_libusb.c b/platform/libusb/hci_transport_h2_libusb.c index ab0f8243c..8694cbdc1 100644 --- a/platform/libusb/hci_transport_h2_libusb.c +++ b/platform/libusb/hci_transport_h2_libusb.c @@ -235,7 +235,33 @@ static void queue_transfer(struct libusb_transfer *transfer){ static void async_callback(struct libusb_transfer *transfer) { - if (libusb_state != LIB_USB_TRANSFERS_ALLOCATED) return; + // identify and free transfers as part of shutdown + if (libusb_state != LIB_USB_TRANSFERS_ALLOCATED) { + int c; + for (c=0;cendpoint, transfer->status, transfer->actual_length ); @@ -921,8 +947,6 @@ static int usb_open(void){ static int usb_close(void){ int c; - // @TODO: remove all run loops! - switch (libusb_state){ case LIB_USB_CLOSED: break; @@ -935,23 +959,6 @@ static int usb_close(void){ usb_timer_active = 0; } - // Cancel any asynchronous transfers - for (c = 0 ; c < ASYNC_BUFFERS ; c++) { - libusb_cancel_transfer(event_in_transfer[c]); - libusb_cancel_transfer(acl_in_transfer[c]); - } -#ifdef ENABLE_SCO_OVER_HCI - // Cancel all synchronous transfer - for (c = 0 ; c < ISOC_BUFFERS ; c++) { - libusb_cancel_transfer(sco_in_transfer[c]); - } -#endif - - /* TODO - find a better way to ensure that all transfers have completed */ - struct timeval tv; - memset(&tv, 0, sizeof(struct timeval)); - libusb_handle_events_timeout(NULL, &tv); - if (doing_pollfds){ int r; for (r = 0 ; r < num_pollfds ; r++) { @@ -965,20 +972,51 @@ static int usb_close(void){ } case LIB_USB_INTERFACE_CLAIMED: - // Cancel any asynchronous transfers + // Cancel all transfers, ignore warnings for this + libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_ERROR); for (c = 0 ; c < ASYNC_BUFFERS ; c++) { libusb_cancel_transfer(event_in_transfer[c]); libusb_cancel_transfer(acl_in_transfer[c]); } #ifdef ENABLE_SCO_OVER_HCI - // Cancel all synchronous transfer for (c = 0 ; c < ISOC_BUFFERS ; c++) { libusb_cancel_transfer(sco_in_transfer[c]); } #endif + libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING); - // TODO free control and acl out transfers + // wait until all transfers are completed + int completed = 0; + while (!completed){ + struct timeval tv; + memset(&tv, 0, sizeof(struct timeval)); + libusb_handle_events_timeout(NULL, &tv); + // check if all done + completed = 1; + for (c=0;c