From ddf9e08069406be1beb95ce3ac00ae59731a6d78 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 3 Oct 2010 16:08:34 +0100 Subject: [PATCH] Make get_subsystem safe during destruction of the manager. --- simgear/structure/subsystem_mgr.cxx | 30 +++++++++++++++++++-- simgear/structure/subsystem_mgr.hxx | 42 ++++++++++++++++------------- 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx index 9488faea..6b50645e 100644 --- a/simgear/structure/subsystem_mgr.cxx +++ b/simgear/structure/subsystem_mgr.cxx @@ -387,6 +387,9 @@ SGSubsystemMgr::SGSubsystemMgr () SGSubsystemMgr::~SGSubsystemMgr () { + // ensure get_subsystem returns NULL from now onwards, + // before the SGSubsystemGroup destructors are run + _subsystem_map.clear(); } void @@ -475,6 +478,29 @@ SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem, _subsystem_map[name] = subsystem; } +SGSubsystem* +SGSubsystemMgr::remove(const char* name) +{ + SubsystemDict::iterator s =_subsystem_map.find(name); + if (s == _subsystem_map.end()) { + return NULL; + } + + SGSubsystem* sub = s->second; + _subsystem_map.erase(s); + +// tedious part - we don't know which group the subsystem belongs too + for (int i = 0; i < MAX_GROUPS; i++) { + if (_groups[i].get_subsystem(name) == sub) { + _groups[i].remove_subsystem(name); + break; + } + } // of groups iteration + + return sub; +} + + SGSubsystemGroup * SGSubsystemMgr::get_group (GroupType group) { @@ -482,9 +508,9 @@ SGSubsystemMgr::get_group (GroupType group) } SGSubsystem * -SGSubsystemMgr::get_subsystem (const string &name) +SGSubsystemMgr::get_subsystem (const string &name) const { - map::iterator s =_subsystem_map.find(name); + SubsystemDict::const_iterator s =_subsystem_map.find(name); if (s == _subsystem_map.end()) return 0; diff --git a/simgear/structure/subsystem_mgr.hxx b/simgear/structure/subsystem_mgr.hxx index 5b449cca..212ce584 100644 --- a/simgear/structure/subsystem_mgr.hxx +++ b/simgear/structure/subsystem_mgr.hxx @@ -29,10 +29,6 @@ #include #include -using std::map; -using std::vector; -using std::string; - #include #include #include "SGSmplstat.hxx" @@ -41,19 +37,19 @@ using std::string; class TimingInfo { private: - string eventName; + std::string eventName; SGTimeStamp time; public: - TimingInfo(const string& name, const SGTimeStamp &t) : + TimingInfo(const std::string& name, const SGTimeStamp &t) : eventName(name), time(t) { } - const string& getName() const { return eventName; } + const std::string& getName() const { return eventName; } const SGTimeStamp& getTime() const { return time; } }; -typedef vector eventTimeVec; -typedef vector::iterator eventTimeVecIterator; +typedef std::vector eventTimeVec; +typedef std::vector::iterator eventTimeVecIterator; @@ -273,7 +269,7 @@ public: * Place time stamps at strategic points in the execution of subsystems * update() member functions. Predominantly for debugging purposes. */ - void stamp(const string& name); + void stamp(const std::string& name); @@ -308,12 +304,12 @@ public: virtual void resume (); virtual bool is_suspended () const; - virtual void set_subsystem (const string &name, + virtual void set_subsystem (const std::string &name, SGSubsystem * subsystem, double min_step_sec = 0); - virtual SGSubsystem * get_subsystem (const string &name); - virtual void remove_subsystem (const string &name); - virtual bool has_subsystem (const string &name) const; + virtual SGSubsystem * get_subsystem (const std::string &name); + virtual void remove_subsystem (const std::string &name); + virtual bool has_subsystem (const std::string &name) const; void collectDebugTiming(bool collect); @@ -339,7 +335,7 @@ private: void collectDebugTiming (bool collect) { collectTimeStats = collect; }; SampleStatistic timeStat; - string name; + std::string name; SGSubsystem * subsystem; double min_step_sec; double elapsed_sec; @@ -347,9 +343,9 @@ private: int exceptionCount; }; - Member * get_member (const string &name, bool create = false); + Member * get_member (const std::string &name, bool create = false); - vector _members; + std::vector _members; double _fixedUpdateTime; double _updateTimeRemainder; @@ -408,16 +404,24 @@ public: GroupType group = GENERAL, double min_time_sec = 0); + /** + * remove a subsystem, and return a pointer to it. + * returns NULL if the subsystem was not found. + */ + virtual SGSubsystem* remove(const char* name); + virtual SGSubsystemGroup * get_group (GroupType group); - virtual SGSubsystem * get_subsystem(const string &name); + virtual SGSubsystem * get_subsystem(const std::string &name) const; void collectDebugTiming(bool collect); private: SGSubsystemGroup _groups[MAX_GROUPS]; - map _subsystem_map; + + typedef std::map SubsystemDict; + SubsystemDict _subsystem_map; }; -- 2.39.5