mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	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:
		| @@ -94,6 +94,7 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition( | |||||||
|  |  | ||||||
| void BeidouB1iPcpsAcquisition::stop_acquisition() | void BeidouB1iPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -92,6 +92,7 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition( | |||||||
|  |  | ||||||
| void BeidouB3iPcpsAcquisition::stop_acquisition() | void BeidouB3iPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -121,6 +121,7 @@ GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition( | |||||||
|  |  | ||||||
| void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition() | void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -94,6 +94,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( | |||||||
|  |  | ||||||
| void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition() | void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -114,6 +114,8 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition | |||||||
|  |  | ||||||
| void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition() | void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -155,6 +155,8 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui | |||||||
|  |  | ||||||
| void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition() | void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -125,6 +125,8 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition( | |||||||
|  |  | ||||||
| void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition() | void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -130,6 +130,8 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf( | |||||||
|  |  | ||||||
| void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition() | void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -93,6 +93,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con | |||||||
|  |  | ||||||
| void GalileoE5aPcpsAcquisition::stop_acquisition() | void GalileoE5aPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -94,6 +94,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( | |||||||
|  |  | ||||||
| void GlonassL1CaPcpsAcquisition::stop_acquisition() | void GlonassL1CaPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -93,6 +93,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( | |||||||
|  |  | ||||||
| void GlonassL2CaPcpsAcquisition::stop_acquisition() | void GlonassL2CaPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -96,6 +96,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|  |  | ||||||
| void GpsL1CaPcpsAcquisition::stop_acquisition() | void GpsL1CaPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -100,6 +100,8 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( | |||||||
|  |  | ||||||
| void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition() | void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -92,6 +92,8 @@ GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition( | |||||||
|  |  | ||||||
| void GpsL1CaPcpsAssistedAcquisition::stop_acquisition() | void GpsL1CaPcpsAssistedAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -119,6 +119,8 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition( | |||||||
|  |  | ||||||
| void GpsL1CaPcpsOpenClAcquisition::stop_acquisition() | void GpsL1CaPcpsOpenClAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -148,6 +148,8 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition( | |||||||
|  |  | ||||||
| void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition() | void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -110,6 +110,8 @@ GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition( | |||||||
|  |  | ||||||
| void GpsL1CaPcpsTongAcquisition::stop_acquisition() | void GpsL1CaPcpsTongAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_cc_->set_state(0); | ||||||
|  |     acquisition_cc_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -93,6 +93,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( | |||||||
|  |  | ||||||
| void GpsL2MPcpsAcquisition::stop_acquisition() | void GpsL2MPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -94,6 +94,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( | |||||||
|  |  | ||||||
| void GpsL5iPcpsAcquisition::stop_acquisition() | void GpsL5iPcpsAcquisition::stop_acquisition() | ||||||
| { | { | ||||||
|  |     acquisition_->set_active(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -84,10 +84,10 @@ public: | |||||||
|     void msg_handler_events(pmt::pmt_t msg); |     void msg_handler_events(pmt::pmt_t msg); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     std::shared_ptr<ChannelFsm> channel_fsm_; | ||||||
|     std::shared_ptr<AcquisitionInterface> acq_; |     std::shared_ptr<AcquisitionInterface> acq_; | ||||||
|     std::shared_ptr<TrackingInterface> trk_; |     std::shared_ptr<TrackingInterface> trk_; | ||||||
|     std::shared_ptr<TelemetryDecoderInterface> nav_; |     std::shared_ptr<TelemetryDecoderInterface> nav_; | ||||||
|     std::shared_ptr<ChannelFsm> channel_fsm_; |  | ||||||
|     channel_msg_receiver_cc_sptr channel_msg_rx_; |     channel_msg_receiver_cc_sptr channel_msg_rx_; | ||||||
|     Concurrent_Queue<pmt::pmt_t>* queue_; |     Concurrent_Queue<pmt::pmt_t>* queue_; | ||||||
|     Gnss_Synchro gnss_synchro_{}; |     Gnss_Synchro gnss_synchro_{}; | ||||||
|   | |||||||
| @@ -102,6 +102,7 @@ ControlThread::ControlThread(std::shared_ptr<ConfigurationInterface> configurati | |||||||
|  |  | ||||||
| void ControlThread::init() | 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 |     // 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); |     pre_2009_file_ = configuration_->property("GNSS-SDR.pre_2009_file", false); | ||||||
|     // Instantiates a control queue, a GNSS flowgraph, and a control message factory |     // 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()) |     if (cmd_interface_thread_.joinable()) | ||||||
|         { |         { | ||||||
|             cmd_interface_thread_.detach(); |             cmd_interface_thread_.join(); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void ControlThread::telecommand_listener() | 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); |             int tcp_cmd_port = configuration_->property("GNSS-SDR.telecommand_tcp_port", 3333); | ||||||
|             cmd_interface_.run_cmd_server(tcp_cmd_port); |             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)); |     fpga_helper_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(500)); |  | ||||||
|     // Terminate keyboard thread |     // Terminate keyboard thread | ||||||
|     pthread_t id = keyboard_thread_.native_handle(); |     pthread_t id = keyboard_thread_.native_handle(); | ||||||
|     keyboard_thread_.detach(); |     keyboard_thread_.detach(); | ||||||
|     pthread_cancel(id); |     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"; |     LOG(INFO) << "Flowgraph stopped"; | ||||||
|  |  | ||||||
|     if (restart_) |     if (restart_) | ||||||
|   | |||||||
| @@ -147,19 +147,6 @@ private: | |||||||
|     void keyboard_listener(); |     void keyboard_listener(); | ||||||
|     void sysv_queue_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 |     // default filename for assistance data | ||||||
|     const std::string eph_default_xml_filename_ = "./gps_ephemeris.xml"; |     const std::string eph_default_xml_filename_ = "./gps_ephemeris.xml"; | ||||||
|     const std::string utc_default_xml_filename_ = "./gps_utc_model.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 gal_almanac_default_xml_filename_ = "./gal_almanac.xml"; | ||||||
|     const std::string gps_almanac_default_xml_filename_ = "./gps_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_; |     TcpCmdInterface cmd_interface_; | ||||||
|  |  | ||||||
|     // SUPL assistance classes |     // SUPL assistance classes | ||||||
| @@ -196,6 +196,7 @@ private: | |||||||
|     bool receiver_on_standby_; |     bool receiver_on_standby_; | ||||||
|     bool stop_; |     bool stop_; | ||||||
|     bool restart_; |     bool restart_; | ||||||
|  |     bool telecommand_enabled_; | ||||||
|     bool pre_2009_file_;  // to override the system time to postprocess old gnss records and avoid wrong week rollover |     bool pre_2009_file_;  // to override the system time to postprocess old gnss records and avoid wrong week rollover | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -114,6 +114,10 @@ void GNSSFlowgraph::start() | |||||||
|  |  | ||||||
| void GNSSFlowgraph::stop() | void GNSSFlowgraph::stop() | ||||||
| { | { | ||||||
|  |     for (auto chan : channels_) | ||||||
|  |         { | ||||||
|  |             chan->stop_channel();  // stop the acquisition or tracking operation | ||||||
|  |         } | ||||||
|     top_block_->stop(); |     top_block_->stop(); | ||||||
|     running_ = false; |     running_ = false; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -135,6 +135,7 @@ TEST_F(ControlThreadTest /*unused*/, InstantiateRunControlMessages /*unused*/) | |||||||
|     unsigned int expected1 = 1; |     unsigned int expected1 = 1; | ||||||
|     EXPECT_EQ(expected3, control_thread->processed_control_messages()); |     EXPECT_EQ(expected3, control_thread->processed_control_messages()); | ||||||
|     EXPECT_EQ(expected1, control_thread->applied_actions()); |     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; |     unsigned int expected1 = 1; | ||||||
|     EXPECT_EQ(expected5, control_thread2->processed_control_messages()); |     EXPECT_EQ(expected5, control_thread2->processed_control_messages()); | ||||||
|     EXPECT_EQ(expected1, control_thread2->applied_actions()); |     EXPECT_EQ(expected1, control_thread2->applied_actions()); | ||||||
|  |     std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez