diff options
author | Josh Blum <josh@joshknows.com> | 2011-09-02 14:08:01 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-09-02 14:08:01 -0700 |
commit | 833da5c1ee138cf2c2e24968fa8cf48c6534a877 (patch) | |
tree | 40a2e1d3c66d189116b83d553b358a06f0446ef3 | |
parent | 0cbafd02667ed6125e6ba9a7c31bedb6e74c1fcb (diff) | |
download | uhd-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.cpp | 26 |
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){ |