aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <ttsou@vt.edu>2012-03-29 19:51:43 -0400
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2013-06-24 01:51:02 +0400
commit5d64491f9b8275d7e573a6aac83a544770b5f452 (patch)
treeb0c1b1e07bfd7693b8467f4d9bcafc0ebc8ad6f9
parentb5c450dfdffe5b74c8482e222cd782a23fcc0065 (diff)
transceiver, uhd: dynamically allocate async event thread
Similar to the previous commit titled, "multi-arfcn, trx: allocate threads on heap and fix thread release" there is the potential for a segfault on exit if the event thread is never started. As before, address the issue by initializing the Thread pointer with NULL and later allocating the object immediately prior to use. On stop or exit, allow the thread to exit by checking a condition variable. If device is stopped or never started, the same variable can be checked for state, which avoids attempts to deallocate an empty pointer. If there is a better method to shutdown / deallocate using the OpenBTS thread library, please let me know. Signed-off-by: Thomas Tsou <ttsou@vt.edu>
-rw-r--r--Transceiver52M/UHDDevice.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index 7b48cff..bd8e1c3 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -265,6 +265,7 @@ public:
@return true if message received or false on timeout or error
*/
bool recv_async_msg();
+ bool running() { return started; }
enum err_code {
ERROR_TIMING = -1,
@@ -310,12 +311,12 @@ private:
std::string str_code(uhd::rx_metadata_t metadata);
std::string str_code(uhd::async_metadata_t metadata);
- Thread async_event_thrd;
+ Thread *async_event_thrd;
};
void *async_event_loop(uhd_device *dev)
{
- while (1) {
+ while (dev->running()) {
dev->recv_async_msg();
pthread_testcancel();
}
@@ -349,6 +350,7 @@ uhd_device::uhd_device(int sps, bool skip_rx)
tx_freq(0.0), rx_freq(0.0), tx_spp(0), rx_spp(0),
started(false), aligned(false), rx_pkt_cnt(0), drop_cnt(0),
prev_ts(0,0), ts_offset(0), rx_smpl_buf(NULL)
+ async_event_thrd(NULL)
{
this->sps = sps;
this->skip_rx = skip_rx;
@@ -677,10 +679,12 @@ bool uhd_device::start()
return false;
}
+ started = true;
setPriority();
// Start asynchronous event (underrun check) loop
- async_event_thrd.start((void * (*)(void*))async_event_loop, (void*)this);
+ async_event_thrd = new Thread(32768);
+ async_event_thrd->start((void * (*)(void*))async_event_loop, (void*)this);
// Start streaming
restart(uhd::time_spec_t(0.0));
@@ -689,18 +693,23 @@ bool uhd_device::start()
double time_now = usrp_dev->get_time_now().get_real_secs();
LOG(INFO) << "The current time is " << time_now << " seconds";
- started = true;
return true;
}
bool uhd_device::stop()
{
+ if (!started)
+ return false;
+
+ started = false;
+
uhd::stream_cmd_t stream_cmd =
uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
usrp_dev->issue_stream_cmd(stream_cmd);
- started = false;
+ delete async_event_thrd;
+
return true;
}