aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Rossetto <aaron.rossetto@ni.com>2021-08-19 08:27:24 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2021-08-20 15:54:56 -0500
commit0382a1c1cc8f5296025420507c8dc9d409a39502 (patch)
tree378403c0118c762cdcd3d529bd065a273a92de4f
parent3a36577a30ead6d616ffb8cc23fe9b57b40a2647 (diff)
downloaduhd-0382a1c1cc8f5296025420507c8dc9d409a39502.tar.gz
uhd-0382a1c1cc8f5296025420507c8dc9d409a39502.tar.bz2
uhd-0382a1c1cc8f5296025420507c8dc9d409a39502.zip
uhd: streamer: Restore original recv(0) semantics
A recv() of zero samples on an RX stream should return immediately (i.e., without respect to the timeout and regardless of the availability of samples), surfacing any stream error conditions via metadata. This convention was broken in a2f10ee9, causing a recv() of zero samples to wait for the entire timeout period and then return ERROR_CODE_TIMEOUT if no samples are available. This commit restores the desired semantics.
-rw-r--r--host/lib/include/uhdlib/transport/rx_streamer_impl.hpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp b/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp
index 00ce558b8..79c196f3f 100644
--- a/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp
+++ b/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp
@@ -257,6 +257,38 @@ private:
const int32_t timeout_ms,
const size_t buffer_offset_bytes = 0)
{
+ // A request to read zero samples should effectively be a no-op.
+ // However, in 2af10ee9, a change was made to increase the probability
+ // but not guarantee that calling recv() after a radio overflow event
+ // would return the overflow condition to the user. That change
+ // introduced a side effect that a read of zero samples (assuming there
+ // were no samples available) would block for the entirety of the
+ // timeout period and then return ERROR_CODE_TIMEOUT in the RX metadata
+ // for the read. (Prior to this change, there was an explicit check for
+ // a read of zero samples, which would return to the caller
+ // immediately.) This of course is undesirable--a request to read zero
+ // samples should always be fulfilled immediately, regardless of the
+ // availability of samples. Furthermore, reading zero samples is
+ // conventionally used to surface any stream errors, and it's that
+ // behavior we would like to preserve.
+ //
+ // This change to call get_recv_buffs() with a zero timeout when
+ // nsamps_per_buff is zero is an attempt to achieve the best of both
+ // worlds. The call to get_recv_buffs() will surface any stream errors,
+ // but using a timeout of 0 means that we'll return as quickly as
+ // possible (with a maximum latency of 1ms; see
+ // rx_streamer_zero_copy.hpp, line 219 or so). If there's any stream
+ // error, it'll be returned in the metadata. However, if the stream
+ // error is ERROR_CODE_TIMEOUT, we'll simply swallow the error, thus
+ // preserving the old behavior.
+ if (nsamps_per_buff == 0) {
+ _zero_copy_streamer.get_recv_buffs(_in_buffs, metadata, eov_positions, 0);
+ if (metadata.error_code == rx_metadata_t::ERROR_CODE_TIMEOUT) {
+ metadata.error_code = rx_metadata_t::ERROR_CODE_NONE;
+ }
+ return 0;
+ }
+
if (_buff_samps_remaining == 0) {
// Current set of buffers has expired, get the next one
_buff_samps_remaining = _zero_copy_streamer.get_recv_buffs(