aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-10-11 18:21:16 -0700
committerJosh Blum <josh@joshknows.com>2010-10-11 18:21:16 -0700
commitd54fd2abffd8849bf41a5f8084a828e6472ba342 (patch)
tree29a717e09bc0bbec06b6ac4a8a452c9916338184
parent1314feb429b8c2713d9fd0e9da077825d0a9c3bc (diff)
downloaduhd-d54fd2abffd8849bf41a5f8084a828e6472ba342.tar.gz
uhd-d54fd2abffd8849bf41a5f8084a828e6472ba342.tar.bz2
uhd-d54fd2abffd8849bf41a5f8084a828e6472ba342.zip
usrp2: use select rather than manually polling the simple udp socket
-rw-r--r--host/include/uhd/transport/udp_simple.hpp4
-rw-r--r--host/lib/transport/udp_simple.cpp44
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp4
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp5
4 files changed, 26 insertions, 31 deletions
diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp
index c84393ecf..83f895ba9 100644
--- a/host/include/uhd/transport/udp_simple.hpp
+++ b/host/include/uhd/transport/udp_simple.hpp
@@ -73,10 +73,10 @@ public:
* Receive into the provided buffer.
* Blocks until data is received or a timeout occurs.
* \param buff a mutable buffer to receive into
- * \param timeout_ms the timeout in milliseconds
+ * \param timeout the timeout in seconds
* \return the number of bytes received or zero on timeout
*/
- virtual size_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0;
+ virtual size_t recv(const boost::asio::mutable_buffer &buff, double timeout = 0.1) = 0;
};
}} //namespace
diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp
index 89750f99d..5829b462b 100644
--- a/host/lib/transport/udp_simple.cpp
+++ b/host/lib/transport/udp_simple.cpp
@@ -27,23 +27,25 @@ using namespace uhd::transport;
* Helper Functions
**********************************************************************/
/*!
- * A receive timeout for a socket:
- *
- * It seems that asio cannot have timeouts with synchronous io.
- * However, we can implement a polling loop that will timeout.
- * This is okay bacause this is the slow-path implementation.
- *
+ * Wait for available data or timeout.
* \param socket the asio socket
- * \param timeout_ms the timeout in milliseconds
+ * \param timeout the timeout in seconds
+ * \return false for timeout, true for data
*/
-static void reasonable_recv_timeout(
- boost::asio::ip::udp::socket &socket, size_t timeout_ms
+static bool wait_available(
+ boost::asio::ip::udp::socket &socket, double timeout
){
- boost::asio::deadline_timer timer(socket.get_io_service());
- timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
- while (not (socket.available() or timer.expires_from_now().is_negative())){
- boost::this_thread::sleep(boost::posix_time::milliseconds(1));
- }
+ //setup timeval for timeout
+ timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = long(timeout*1e6);
+
+ //setup rset for timeout
+ fd_set rset;
+ FD_ZERO(&rset);
+ FD_SET(socket.native(), &rset);
+
+ return ::select(socket.native()+1, &rset, NULL, NULL, &tv) > 0;
}
/***********************************************************************
@@ -57,7 +59,7 @@ public:
//send/recv
size_t send(const boost::asio::const_buffer &);
- size_t recv(const boost::asio::mutable_buffer &, size_t);
+ size_t recv(const boost::asio::mutable_buffer &, double);
private:
boost::asio::ip::udp::socket *_socket;
@@ -86,9 +88,8 @@ size_t udp_connected_impl::send(const boost::asio::const_buffer &buff){
return _socket->send(boost::asio::buffer(buff));
}
-size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){
- reasonable_recv_timeout(*_socket, timeout_ms);
- if (not _socket->available()) return 0;
+size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){
+ if (not wait_available(*_socket, timeout)) return 0;
return _socket->receive(boost::asio::buffer(buff));
}
@@ -103,7 +104,7 @@ public:
//send/recv
size_t send(const boost::asio::const_buffer &);
- size_t recv(const boost::asio::mutable_buffer &, size_t);
+ size_t recv(const boost::asio::mutable_buffer &, double);
private:
boost::asio::ip::udp::socket *_socket;
@@ -137,9 +138,8 @@ size_t udp_broadcast_impl::send(const boost::asio::const_buffer &buff){
return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint);
}
-size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){
- reasonable_recv_timeout(*_socket, timeout_ms);
- if (not _socket->available()) return 0;
+size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){
+ if (not wait_available(*_socket, timeout)) return 0;
boost::asio::ip::udp::endpoint sender_endpoint;
return _socket->receive_from(boost::asio::buffer(buff), sender_endpoint);
}
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index 6fdde7b2e..55c42567e 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -30,8 +30,6 @@
using namespace uhd;
using namespace uhd::transport;
-static const size_t CONTROL_TIMEOUT_MS = 200;
-
class usrp2_iface_impl : public usrp2_iface{
public:
/***********************************************************************
@@ -177,7 +175,7 @@ public:
boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv
const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);
while(true){
- size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CONTROL_TIMEOUT_MS);
+ size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem));
if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){
throw std::runtime_error(str(boost::format(
"Expected protocol compatibility number %d, but got %d:\n"
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 79bf2b260..1d9f25019 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -35,9 +35,6 @@ using namespace uhd::usrp;
using namespace uhd::transport;
namespace asio = boost::asio;
-//! wait this long for a control response when discovering devices
-static const size_t DISCOVERY_TIMEOUT_MS = 100;
-
/***********************************************************************
* Helper Functions
**********************************************************************/
@@ -99,7 +96,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){
boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv
const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);
while(true){
- size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem), DISCOVERY_TIMEOUT_MS);
+ size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem));
//std::cout << len << "\n";
if (len > offsetof(usrp2_ctrl_data_t, data)){
//handle the received data