1. _running is guarded with a lock in the rtl event loop epilogue.
this prevents a possible hang that could arise from _buf_cond
being notified prior to work() waiting on _buf_cond, but after
work() checks _running.
2. _buf_used is guarded with a lock in the work function to prevent
it from spuriously reading zero if it is nonatomically written
from the rtl event callback.
---
lib/rtl/rtl_source_c.cc | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc
index a371464..bbd0140 100644
--- a/lib/rtl/rtl_source_c.cc
+++ b/lib/rtl/rtl_source_c.cc
@@ -323,7 +323,11 @@ void rtl_source_c::rtlsdr_wait()
{
int ret = rtlsdr_read_async( _dev, _rtlsdr_callback, (void *)this, _buf_num, _buf_len
);
- _running = false;
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ _running = false;
+ }
if ( ret != 0 )
std::cerr << "rtlsdr_read_async returned with " << ret <<
std::endl;
@@ -347,7 +351,7 @@ int rtl_source_c::work( int noutput_items,
if (!_running)
return WORK_DONE;
- while (noutput_items && _buf_used) {
+ while (noutput_items) {
const int nout = std::min(noutput_items, _samp_avail);
const unsigned char *buf = _buf[_buf_head] + _buf_offset * 2;
@@ -363,6 +367,9 @@ int rtl_source_c::work( int noutput_items,
_buf_head = (_buf_head + 1) % _buf_num;
_buf_used--;
+
+ if (_buf_used == 0)
+ break;
}
_samp_avail = _buf_len / BYTES_PER_SAMPLE;
_buf_offset = 0;
--
2.11.0
Show replies by date