From f05ff37560dd4ec4824554e1291f74876890736d Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 23 Oct 2018 15:29:31 +0100 Subject: [PATCH] Fix for assert with empty systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Empty subsystem groups didn’t set their init state correctly, leading to an assert on post-init. Fix this and add a test for it. https://sourceforge.net/p/flightgear/codetickets/2043/ --- simgear/structure/subsystem_mgr.cxx | 1 + simgear/structure/subsystem_test.cxx | 29 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx index 537649e2..a7294f5f 100644 --- a/simgear/structure/subsystem_mgr.cxx +++ b/simgear/structure/subsystem_mgr.cxx @@ -253,6 +253,7 @@ SGSubsystemGroup::incrementalInit() { // special case this, simplifies the logic below if (_members.empty()) { + _state = State::INIT; return INIT_DONE; } diff --git a/simgear/structure/subsystem_test.cxx b/simgear/structure/subsystem_test.cxx index a1136a78..219a3244 100644 --- a/simgear/structure/subsystem_test.cxx +++ b/simgear/structure/subsystem_test.cxx @@ -314,6 +314,7 @@ void testIncrementalInit() instruments->set_subsystem(radio1); instruments->set_subsystem(radio2); + manager->bind(); for ( ; ; ) { auto status = manager->incrementalInit(); @@ -338,9 +339,34 @@ void testIncrementalInit() SG_VERIFY(d->hasEvent("fake-radio.nav2-will-init")); SG_VERIFY(d->hasEvent("fake-radio.nav2-did-init")); +} +void testEmptyGroup() +{ + // testing the assert described here: + // https://sourceforge.net/p/flightgear/codetickets/2043/ + // when an empty group is inited, we skipped setting the state + + SGSharedPtr manager = new SGSubsystemMgr; + auto d = new RecorderDelegate; + manager->addDelegate(d); + + auto mySub = manager->add(SGSubsystemMgr::POST_FDM); + auto anotherSub = manager->add(SGSubsystemMgr::POST_FDM); + auto instruments = manager->add(SGSubsystemMgr::POST_FDM); + + manager->bind(); + for ( ; ; ) { + auto status = manager->incrementalInit(); + if (status == SGSubsystemMgr::INIT_DONE) + break; + } + manager->postinit(); + + SG_VERIFY(mySub->wasInited); - + SG_VERIFY(d->hasEvent("instruments-will-init")); + SG_VERIFY(d->hasEvent("instruments-did-init")); } void testSuspendResume() @@ -520,6 +546,7 @@ int main(int argc, char* argv[]) testSuspendResume(); testPropertyRoot(); testAddRemoveAfterInit(); + testEmptyGroup(); cout << __FILE__ << ": All tests passed" << endl; return EXIT_SUCCESS;