diff options
| -rw-r--r-- | host/lib/include/uhdlib/transport/rx_streamer_impl.hpp | 32 | 
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( | 
