diff options
| author | Martin Braun <martin.braun@ettus.com> | 2020-04-10 11:39:42 -0700 | 
|---|---|---|
| committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-04-13 07:19:42 -0500 | 
| commit | 3b59529e71549976eaa99b75f40df732a8b73d6d (patch) | |
| tree | eceb0bc28675b0a0a7ecf2d052c15ac8546d21ef /host | |
| parent | b6ff5fd2837bed63b09798e4fa187b169b7dcdc2 (diff) | |
| download | uhd-3b59529e71549976eaa99b75f40df732a8b73d6d.tar.gz uhd-3b59529e71549976eaa99b75f40df732a8b73d6d.tar.bz2 uhd-3b59529e71549976eaa99b75f40df732a8b73d6d.zip  | |
multi_usrp: Approximate legacy behaviour for recv_async_msg()
When using multi_usrp with an RFNoC device, the previous behaviour was
to throw an exception when calling recv_async_msg() so users would know
they're not supposed to call it (calling tx_stream::recv_async_msg is
preferred). However, this breaks too many existing applications.
Instead, we keep a weak pointer to the streamer, the same way that older
devices do, and query the async message from that. This means that
calling recv_async_msg() when there are multiple streamers can lead to
unexpected behaviour, but that's a general issue with
multi_usrp::recv_async_msg() and this way, the RFNoC devices now behave
like older devices do.
Diffstat (limited to 'host')
| -rw-r--r-- | host/include/uhd/device.hpp | 11 | ||||
| -rw-r--r-- | host/include/uhd/usrp/multi_usrp.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/multi_usrp_rfnoc.cpp | 34 | 
3 files changed, 34 insertions, 13 deletions
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index 38424c866..7fffc59b6 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -87,18 +87,15 @@ public:       */      virtual tx_streamer::sptr get_tx_stream(const stream_args_t& args) = 0; -    /*! Receive asynchronous message from the device +    /*! DEPRECATED: Receive asynchronous message from the device       * -     * Note that when calling multi_usrp::get_device() on an RFNoC-capable device, -     * the returned uhd::device (while still being a valid object) will not be -     * able to execute this method. Instead, query the asynchronous messages -     * from the appropriate Tx streamer. +     * Prefer calling recv_async_msg on the associated TX streamer. This method +     * has the problem that it doesn't necessarily know which Tx streamer is +     * being addressed, and thus might not be delivering the expected outcome.       *       * \param async_metadata the metadata to be filled in       * \param timeout the timeout in seconds to wait for a message       * \return true when the async_metadata is valid, false for timeout -     * \throws uhd::runtime_error if called on a device returned by -     *         multi_usrp::get_device on an RFNoC device.       */      virtual bool recv_async_msg(          async_metadata_t& async_metadata, double timeout = 0.1) = 0; diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 5d86370c6..53e63361f 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -129,7 +129,7 @@ public:       * For RFNoC devices, this won't return a true uhd::device anyway, because       * direct device access is locked for those. The returned pointer will       * still point to a valid device object, however, it has reduced -     * functionality (in particular, recv_async_msg() won't work). +     * functionality.       *       * \return the device object within this USRP       */ diff --git a/host/lib/usrp/multi_usrp_rfnoc.cpp b/host/lib/usrp/multi_usrp_rfnoc.cpp index f81253997..14b5fd50b 100644 --- a/host/lib/usrp/multi_usrp_rfnoc.cpp +++ b/host/lib/usrp/multi_usrp_rfnoc.cpp @@ -56,6 +56,7 @@ constexpr char DEFAULT_CPU_FORMAT[] = "fc32";  constexpr char DEFAULT_OTW_FORMAT[] = "sc16";  constexpr double RX_SIGN            = +1.0;  constexpr double TX_SIGN            = -1.0; +constexpr char LOG_ID[]             = "MULTI_USRP";  //! A faux container for a UHD device  // @@ -64,7 +65,10 @@ constexpr double TX_SIGN            = -1.0;  // similar functionalities; these can be faked with this redirector class.  //  // The only exception is recv_async_msg(), which depends on the streamer. It -// will throw a uhd::runtime_error now. +// will print a warning once, and will attempt to access a Tx streamer if it +// has access to a Tx streamer. If there is only ever one Tx streamer, this will +// work as expected. For multiple streamers, only the last streamer's async +// messages will make it through.  class redirector_device : public uhd::device  {  public: @@ -77,13 +81,22 @@ public:      tx_streamer::sptr get_tx_stream(const stream_args_t& args)      { -        return _musrp->get_tx_stream(args); +        auto streamer = _musrp->get_tx_stream(args); +        _last_tx_streamer = streamer; +        return streamer;      } -    bool recv_async_msg(async_metadata_t&, double) +    bool recv_async_msg(async_metadata_t& md, double timeout)      { -        throw uhd::runtime_error( -            "uhd::device::recv_async_msg() cannot be called on this device type!"); +        std::call_once(_async_warning_flag, []() { +            UHD_LOG_WARNING(LOG_ID, +                "Calling multi_usrp::recv_async_msg() is deprecated and can lead to " +                "unexpected behaviour. Prefer calling tx_stream::recv_async_msg()."); +        }); +        auto streamer = _last_tx_streamer.lock(); +        if (streamer) { +            return streamer->recv_async_msg(md, timeout); +        }          return false;      } @@ -97,7 +110,14 @@ public:          return USRP;      } +    void set_tx_stream(tx_streamer::sptr streamer) +    { +        _last_tx_streamer = streamer; +    } +  private: +    std::once_flag _async_warning_flag; +    std::weak_ptr<tx_streamer> _last_tx_streamer;      multi_usrp* _musrp;  }; @@ -380,6 +400,10 @@ public:                  }              }          } +        // For legacy purposes: This enables recv_async_msg(), which is considered +        // deprecated, but as long as it's there, we need this to approximate +        // previous behaviour. +        _device->set_tx_stream(tx_streamer);          return tx_streamer;      }  | 
