diff options
| author | michael-west <michael.west@ettus.com> | 2017-03-08 17:16:10 -0800 | 
|---|---|---|
| committer | Martin Braun <martin.braun@ettus.com> | 2017-04-05 17:26:28 -0700 | 
| commit | 7f7d9b04cfc59a8dd743ff3dc9c816b57675786e (patch) | |
| tree | d98b2c26b0ef555c594bf46f3fc22c5258b1d0b2 | |
| parent | 47d5f6651a05714f0cad55bd4c225a049abd5ef8 (diff) | |
| download | uhd-7f7d9b04cfc59a8dd743ff3dc9c816b57675786e.tar.gz uhd-7f7d9b04cfc59a8dd743ff3dc9c816b57675786e.tar.bz2 uhd-7f7d9b04cfc59a8dd743ff3dc9c816b57675786e.zip  | |
Fix bounded buffer functions so they don't release the lock before waiting on condition variables.
| -rw-r--r-- | host/include/uhd/transport/bounded_buffer.ipp | 89 | 
1 files changed, 55 insertions, 34 deletions
diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp index 35ffb293b..daca3f04f 100644 --- a/host/include/uhd/transport/bounded_buffer.ipp +++ b/host/include/uhd/transport/bounded_buffer.ipp @@ -28,7 +28,8 @@  namespace uhd{ namespace transport{ -    template <typename elem_type> class bounded_buffer_detail : boost::noncopyable{ +    template <typename elem_type> class bounded_buffer_detail : boost::noncopyable +    {      public:          bounded_buffer_detail(size_t capacity): @@ -38,79 +39,97 @@ namespace uhd{ namespace transport{              _not_empty_fcn = boost::bind(&bounded_buffer_detail<elem_type>::not_empty, this);          } -        UHD_INLINE bool push_with_haste(const elem_type &elem){ +        UHD_INLINE bool push_with_haste(const elem_type &elem) +        {              boost::mutex::scoped_lock lock(_mutex); -            if (_buffer.full()) return false; +            if (_buffer.full()) +            { +                return false; +            }              _buffer.push_front(elem); -            lock.unlock();              _empty_cond.notify_one();              return true;          } -        UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){ +        UHD_INLINE bool push_with_pop_on_full(const elem_type &elem) +        {              boost::mutex::scoped_lock lock(_mutex); -            if (_buffer.full()){ +            if (_buffer.full()) +            {                  _buffer.pop_back();                  _buffer.push_front(elem); -                lock.unlock();                  _empty_cond.notify_one();                  return false;              } -            else{ +            else {                  _buffer.push_front(elem); -                lock.unlock();                  _empty_cond.notify_one();                  return true;              }          } -        UHD_INLINE void push_with_wait(const elem_type &elem){ -            if (this->push_with_haste(elem)) return; +        UHD_INLINE void push_with_wait(const elem_type &elem) +        {              boost::mutex::scoped_lock lock(_mutex); -            _full_cond.wait(lock, _not_full_fcn); +            if (_buffer.full()) +            { +                _full_cond.wait(lock, _not_full_fcn); +            }              _buffer.push_front(elem); -            lock.unlock();              _empty_cond.notify_one();          } -        UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout){ -            if (this->push_with_haste(elem)) return true; +        UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout) +        {              boost::mutex::scoped_lock lock(_mutex); -            if (not _full_cond.timed_wait( -                lock, to_time_dur(timeout), _not_full_fcn -            )) return false; +            if (_buffer.full()) +            { +                if (not _full_cond.timed_wait(lock, +                    to_time_dur(timeout), _not_full_fcn)) +                { +                    return false; +                } +            }              _buffer.push_front(elem); -            lock.unlock();              _empty_cond.notify_one();              return true;          } -        UHD_INLINE bool pop_with_haste(elem_type &elem){ +        UHD_INLINE bool pop_with_haste(elem_type &elem) +        {              boost::mutex::scoped_lock lock(_mutex); -            if (_buffer.empty()) return false; +            if (_buffer.empty())  +            { +                return false; +            }              this->pop_back(elem); -            lock.unlock();              _full_cond.notify_one();              return true;          } -        UHD_INLINE void pop_with_wait(elem_type &elem){ -            if (this->pop_with_haste(elem)) return; +        UHD_INLINE void pop_with_wait(elem_type &elem) +        {              boost::mutex::scoped_lock lock(_mutex); -            _empty_cond.wait(lock, _not_empty_fcn); +            if (_buffer.empty()) +            { +                _empty_cond.wait(lock, _not_empty_fcn); +            }              this->pop_back(elem); -            lock.unlock();              _full_cond.notify_one();          } -        UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout){ -            if (this->pop_with_haste(elem)) return true; +        UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout) +        {              boost::mutex::scoped_lock lock(_mutex); -            if (not _empty_cond.timed_wait( -                lock, to_time_dur(timeout), _not_empty_fcn -            )) return false; +            if (_buffer.empty())  +            { +                if (not _empty_cond.timed_wait(lock, to_time_dur(timeout), +                    _not_empty_fcn)) +                { +                    return false; +                } +            }              this->pop_back(elem); -            lock.unlock();              _full_cond.notify_one();              return true;          } @@ -131,13 +150,15 @@ namespace uhd{ namespace transport{           * 2) assign the back element to empty           * 3) pop the back to move the counter           */ -        UHD_INLINE void pop_back(elem_type &elem){ +        UHD_INLINE void pop_back(elem_type &elem) +        {              elem = _buffer.back();              _buffer.back() = elem_type();              _buffer.pop_back();          } -        static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout){ +        static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout) +        {              return boost::posix_time::microseconds(long(timeout*1e6));          }  | 
