diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index 3525174f8..96a6b9091 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -10,6 +10,7 @@ * */ +#include #include #include #include @@ -155,7 +156,7 @@ struct rf_uhd_handler_t { #if HAVE_ASYNC_THREAD // Asynchronous transmission message thread - bool async_thread_running = false; + std::atomic async_thread_running{false}; std::thread async_thread; std::mutex async_mutex; std::condition_variable async_cvar; @@ -226,9 +227,12 @@ static void log_late(rf_uhd_handler_t* h, bool is_rx) #if HAVE_ASYNC_THREAD static void log_underflow(rf_uhd_handler_t* h) { - // Flag underflow - if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) { - h->tx_state = RF_UHD_IMP_TX_STATE_END_OF_BURST; + { + std::lock_guard tx_lock(h->tx_mutex); + // Flag underflow + if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) { + h->tx_state = RF_UHD_IMP_TX_STATE_END_OF_BURST; + } } if (h->uhd_error_handler != nullptr) { srsran_rf_error_t error; @@ -289,6 +293,7 @@ static void* async_thread(void* h) } } else if (event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) { // Makes sure next block will be start of burst + std::lock_guard tx_lock(handler->tx_mutex); if (handler->tx_state == RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK) { handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST; } @@ -1023,11 +1028,12 @@ double rf_uhd_set_rx_srate(void* h, double freq) double rf_uhd_set_tx_srate(void* h, double freq) { - rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; - std::unique_lock lock(handler->tx_mutex); + rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; + // Locking order should be kept the same with the async worker. #if HAVE_ASYNC_THREAD std::unique_lock lock_async(handler->async_mutex); #endif /* HAVE_ASYNC_THREAD */ + std::unique_lock lock(handler->tx_mutex); // Early return if the current rate matches and Tx stream has been created if (freq == handler->tx_rate and handler->uhd->is_tx_ready()) { @@ -1409,6 +1415,8 @@ int rf_uhd_send_timed_multi(void* h, // Flush receiver only if allowed if (RF_UHD_IMP_PROHIBITED_EOB_FLUSH.count(handler->devname) == 0) { + // Avoid holding the tx lock while in the rf_uhd_flush_buffer function to avoid potential deadlocks. + lock.unlock(); rf_uhd_flush_buffer(h); } diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index e11281191..7babf6a28 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -152,14 +152,14 @@ void enb::stop() { if (started) { // tear down in reverse order - if (radio) { - radio->stop(); - } - if (phy) { phy->stop(); } + if (radio) { + radio->stop(); + } + if (eutra_stack) { eutra_stack->stop(); }