aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-09-02 14:08:01 -0700
committerJosh Blum <josh@joshknows.com>2011-09-02 14:08:01 -0700
commit833da5c1ee138cf2c2e24968fa8cf48c6534a877 (patch)
tree40a2e1d3c66d189116b83d553b358a06f0446ef3
parent0cbafd02667ed6125e6ba9a7c31bedb6e74c1fcb (diff)
downloaduhd-833da5c1ee138cf2c2e24968fa8cf48c6534a877.tar.gz
uhd-833da5c1ee138cf2c2e24968fa8cf48c6534a877.tar.bz2
uhd-833da5c1ee138cf2c2e24968fa8cf48c6534a877.zip
usb: reimplement ~libusb_zero_copy_impl to avoid segfaults and indefinite timeouts
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp26
1 files changed, 13 insertions, 13 deletions
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 4259c42ed..ada664286 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -45,12 +45,6 @@ static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
*(static_cast<bool *>(lut->user_data)) = true;
}
-//! callback to free transfer upon cancellation
-static void LIBUSB_CALL cancel_transfer_cb(libusb_transfer *lut){
- if (lut->status == LIBUSB_TRANSFER_CANCELLED || lut->status == LIBUSB_TRANSFER_TIMED_OUT) libusb_free_transfer(lut);
- else UHD_MSG(error) << "libusb cancel_transfer unexpected status " << lut->status << std::endl;
-}
-
/*!
* Wait for a managed buffer to become complete.
*
@@ -230,16 +224,22 @@ public:
}
~libusb_zero_copy_impl(void){
- //cancel and free all transfers
+ libusb_context *ctx = libusb::session::get_global_session()->get_context();
+
+ //cancel all transfers
BOOST_FOREACH(libusb_transfer *lut, _all_luts){
- lut->callback = libusb_transfer_cb_fn(&cancel_transfer_cb);
libusb_cancel_transfer(lut);
- while(lut->status != LIBUSB_TRANSFER_CANCELLED
- && lut->status != LIBUSB_TRANSFER_COMPLETED
- && lut->status != LIBUSB_TRANSFER_TIMED_OUT) {
- boost::this_thread::sleep(boost::posix_time::milliseconds(10));
- }
}
+
+ //process all transfers until timeout occurs
+ bool completed = false;
+ wait_for_completion(ctx, 0.01, completed);
+
+ //free all transfers
+ BOOST_FOREACH(libusb_transfer *lut, _all_luts){
+ libusb_free_transfer(lut);
+ }
+
}
managed_recv_buffer::sptr get_recv_buff(double timeout){