aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authormichael-west <michael.west@ettus.com>2017-03-08 17:16:10 -0800
committerMartin Braun <martin.braun@ettus.com>2017-04-05 17:26:28 -0700
commit7f7d9b04cfc59a8dd743ff3dc9c816b57675786e (patch)
treed98b2c26b0ef555c594bf46f3fc22c5258b1d0b2 /host/include
parent47d5f6651a05714f0cad55bd4c225a049abd5ef8 (diff)
downloaduhd-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.
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/transport/bounded_buffer.ipp89
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));
}