Fix a bug that could cause a crash on receiver stopping

If a channel event was happening after flowgraph stop and before flowgraph disconnection, it caused a crash. This was avoided by sleeping the control thread during 500 ms after disconnection and before the block destructors were called, so the event could be processed, but this was not a robust solution.
This commit is contained in:
Carles Fernandez 2020-06-27 09:52:59 +02:00
parent 9310bd8460
commit c784dfe125
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
24 changed files with 59 additions and 18 deletions

View File

@ -94,6 +94,7 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
void BeidouB1iPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -92,6 +92,7 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
void BeidouB3iPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -121,6 +121,7 @@ GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition(
void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition()
{
acquisition_cc_->set_active(false);
}

View File

@ -94,6 +94,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -114,6 +114,8 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition
void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -155,6 +155,8 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -125,6 +125,8 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition(
void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -130,6 +130,8 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -93,6 +93,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
void GalileoE5aPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -94,6 +94,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
void GlonassL1CaPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -93,6 +93,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
void GlonassL2CaPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -96,6 +96,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
void GpsL1CaPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -100,6 +100,8 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler(
void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -92,6 +92,8 @@ GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition(
void GpsL1CaPcpsAssistedAcquisition::stop_acquisition()
{
acquisition_cc_->set_active(false);
acquisition_cc_->set_state(0);
}

View File

@ -119,6 +119,8 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition(
void GpsL1CaPcpsOpenClAcquisition::stop_acquisition()
{
acquisition_cc_->set_active(false);
acquisition_cc_->set_state(0);
}

View File

@ -148,6 +148,8 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -110,6 +110,8 @@ GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition(
void GpsL1CaPcpsTongAcquisition::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}

View File

@ -93,6 +93,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
void GpsL2MPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -94,6 +94,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
void GpsL5iPcpsAcquisition::stop_acquisition()
{
acquisition_->set_active(false);
}

View File

@ -84,10 +84,10 @@ public:
void msg_handler_events(pmt::pmt_t msg);
private:
std::shared_ptr<ChannelFsm> channel_fsm_;
std::shared_ptr<AcquisitionInterface> acq_;
std::shared_ptr<TrackingInterface> trk_;
std::shared_ptr<TelemetryDecoderInterface> nav_;
std::shared_ptr<ChannelFsm> channel_fsm_;
channel_msg_receiver_cc_sptr channel_msg_rx_;
Concurrent_Queue<pmt::pmt_t>* queue_;
Gnss_Synchro gnss_synchro_{};

View File

@ -102,6 +102,7 @@ ControlThread::ControlThread(std::shared_ptr<ConfigurationInterface> configurati
void ControlThread::init()
{
telecommand_enabled_ = configuration_->property("GNSS-SDR.telecommand_enabled", false);
// OPTIONAL: specify a custom year to override the system time in order to postprocess old gnss records and avoid wrong week rollover
pre_2009_file_ = configuration_->property("GNSS-SDR.pre_2009_file", false);
// Instantiates a control queue, a GNSS flowgraph, and a control message factory
@ -208,15 +209,14 @@ ControlThread::~ControlThread() // NOLINT(modernize-use-equals-default)
if (cmd_interface_thread_.joinable())
{
cmd_interface_thread_.detach();
cmd_interface_thread_.join();
}
}
void ControlThread::telecommand_listener()
{
bool telecommand_enabled = configuration_->property("GNSS-SDR.telecommand_enabled", false);
if (telecommand_enabled)
if (telecommand_enabled_)
{
int tcp_cmd_port = configuration_->property("GNSS-SDR.telecommand_tcp_port", 3333);
cmd_interface_.run_cmd_server(tcp_cmd_port);
@ -356,12 +356,18 @@ int ControlThread::run()
fpga_helper_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000));
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// Terminate keyboard thread
pthread_t id = keyboard_thread_.native_handle();
keyboard_thread_.detach();
pthread_cancel(id);
if (telecommand_enabled_)
{
pthread_t id2 = cmd_interface_thread_.native_handle();
cmd_interface_thread_.detach();
pthread_cancel(id2);
}
LOG(INFO) << "Flowgraph stopped";
if (restart_)

View File

@ -147,19 +147,6 @@ private:
void keyboard_listener();
void sysv_queue_listener();
std::shared_ptr<ConfigurationInterface> configuration_;
std::shared_ptr<Concurrent_Queue<pmt::pmt_t>> control_queue_;
std::shared_ptr<GNSSFlowgraph> flowgraph_;
std::thread cmd_interface_thread_;
std::thread keyboard_thread_;
std::thread sysv_queue_thread_;
std::thread gps_acq_assist_data_collector_thread_;
#ifdef ENABLE_FPGA
boost::thread fpga_helper_thread_;
#endif
// default filename for assistance data
const std::string eph_default_xml_filename_ = "./gps_ephemeris.xml";
const std::string utc_default_xml_filename_ = "./gps_utc_model.xml";
@ -176,6 +163,19 @@ private:
const std::string gal_almanac_default_xml_filename_ = "./gal_almanac.xml";
const std::string gps_almanac_default_xml_filename_ = "./gps_almanac.xml";
std::shared_ptr<ConfigurationInterface> configuration_;
std::shared_ptr<Concurrent_Queue<pmt::pmt_t>> control_queue_;
std::shared_ptr<GNSSFlowgraph> flowgraph_;
std::thread cmd_interface_thread_;
std::thread keyboard_thread_;
std::thread sysv_queue_thread_;
std::thread gps_acq_assist_data_collector_thread_;
#ifdef ENABLE_FPGA
boost::thread fpga_helper_thread_;
#endif
TcpCmdInterface cmd_interface_;
// SUPL assistance classes
@ -196,6 +196,7 @@ private:
bool receiver_on_standby_;
bool stop_;
bool restart_;
bool telecommand_enabled_;
bool pre_2009_file_; // to override the system time to postprocess old gnss records and avoid wrong week rollover
};

View File

@ -114,6 +114,10 @@ void GNSSFlowgraph::start()
void GNSSFlowgraph::stop()
{
for (auto chan : channels_)
{
chan->stop_channel(); // stop the acquisition or tracking operation
}
top_block_->stop();
running_ = false;
}

View File

@ -135,6 +135,7 @@ TEST_F(ControlThreadTest /*unused*/, InstantiateRunControlMessages /*unused*/)
unsigned int expected1 = 1;
EXPECT_EQ(expected3, control_thread->processed_control_messages());
EXPECT_EQ(expected1, control_thread->applied_actions());
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
@ -196,6 +197,7 @@ TEST_F(ControlThreadTest /*unused*/, InstantiateRunControlMessages2 /*unused*/)
unsigned int expected1 = 1;
EXPECT_EQ(expected5, control_thread2->processed_control_messages());
EXPECT_EQ(expected1, control_thread2->applied_actions());
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}