summaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-04-19 17:47:36 -0700
committerJosh Blum <josh@joshknows.com>2011-04-19 17:47:36 -0700
commitfdee3ba82b997c709e6822aa000df8adb61c56a5 (patch)
treeed566f55ef024fd2a45d053a719010e1b2c49366 /host/lib/transport
parentee424d797fc37a8c3c2a82a58218bf1e85456226 (diff)
parent290bb75de236cb53c54bb4599cc2dde924f9800e (diff)
downloaduhd-fdee3ba82b997c709e6822aa000df8adb61c56a5.tar.gz
uhd-fdee3ba82b997c709e6822aa000df8adb61c56a5.tar.bz2
uhd-fdee3ba82b997c709e6822aa000df8adb61c56a5.zip
Merge branch 'master' into next
Conflicts: fpga/usrp2/top/u2plus/Makefile.N200
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/CMakeLists.txt6
-rw-r--r--host/lib/transport/if_addrs.cpp2
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp40
3 files changed, 38 insertions, 10 deletions
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index a5bf9c5f1..90360977a 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -79,6 +79,12 @@ SET_SOURCE_FILES_PROPERTIES(
PROPERTIES COMPILE_DEFINITIONS "${IF_ADDRS_DEFS}"
)
+#On windows, the boost asio implementation uses the winsock2 library.
+#Note: we exclude the .lib extension for cygwin and mingw platforms.
+IF(WIN32)
+ LIBUHD_APPEND_LIBS(ws2_32)
+ENDIF()
+
########################################################################
# Append to the list of sources for lib uhd
########################################################################
diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp
index b7c8ad844..83a1ee56f 100644
--- a/host/lib/transport/if_addrs.cpp
+++ b/host/lib/transport/if_addrs.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 6dee69711..e42cab1d1 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -24,6 +24,7 @@
#include <boost/function.hpp>
#include <boost/foreach.hpp>
#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
#include <list>
#include <iostream>
@@ -33,11 +34,27 @@ using namespace uhd::transport;
static const size_t DEFAULT_NUM_XFERS = 16; //num xfers
static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
+//! Define LIBUSB_CALL when its missing (non-windows)
+#ifndef LIBUSB_CALL
+ #define LIBUSB_CALL
+#endif /*LIBUSB_CALL*/
+
+/*!
+ * All libusb callback functions should be marked with the LIBUSB_CALL macro
+ * to ensure that they are compiled with the same calling convention as libusb.
+ */
+
//! helper function: handles all async callbacks
-static void libusb_async_cb(libusb_transfer *lut){
+static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
(*static_cast<boost::function<void()> *>(lut->user_data))();
}
+//! callback to free transfer upon cancellation
+static void LIBUSB_CALL cancel_transfer_cb(libusb_transfer *lut){
+ if (lut->status == LIBUSB_TRANSFER_CANCELLED) libusb_free_transfer(lut);
+ else std::cout << "libusb cancel_transfer unexpected status " << lut->status << std::endl;
+}
+
/***********************************************************************
* Reusable managed receiver buffer:
* - Associated with a particular libusb transfer struct.
@@ -185,22 +202,26 @@ public:
//spawn the event handler threads
size_t concurrency = hints.cast<size_t>("concurrency_hint", 1);
+ boost::barrier spawn_barrier(concurrency+1);
for (size_t i = 0; i < concurrency; i++) _thread_group.create_thread(
- boost::bind(&libusb_zero_copy_impl::run_event_loop, this)
+ boost::bind(&libusb_zero_copy_impl::run_event_loop, this, boost::ref(spawn_barrier))
);
+ spawn_barrier.wait();
}
~libusb_zero_copy_impl(void){
- //shutdown the threads
- _threads_running = false;
- _thread_group.interrupt_all();
- _thread_group.join_all();
-
//cancel and free all transfers
BOOST_FOREACH(libusb_transfer *lut, _all_luts){
+ lut->callback = libusb_transfer_cb_fn(&cancel_transfer_cb);
libusb_cancel_transfer(lut);
- libusb_free_transfer(lut);
+ while(lut->status != LIBUSB_TRANSFER_CANCELLED && lut->status != LIBUSB_TRANSFER_COMPLETED) {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+ }
}
+ //shutdown the threads
+ _threads_running = false;
+ _thread_group.interrupt_all();
+ _thread_group.join_all();
}
managed_recv_buffer::sptr get_recv_buff(double timeout){
@@ -255,7 +276,8 @@ private:
boost::thread_group _thread_group;
bool _threads_running;
- void run_event_loop(void){
+ void run_event_loop(boost::barrier &spawn_barrier){
+ spawn_barrier.wait();
set_thread_priority_safe();
libusb_context *context = libusb::session::get_global_session()->get_context();
_threads_running = true;