Make get_subsystem safe during destruction of the manager.

This commit is contained in:
James Turner
2010-10-03 16:08:34 +01:00
parent b5f3978b8a
commit ddf9e08069
2 changed files with 51 additions and 21 deletions
+28 -2
View File
@@ -387,6 +387,9 @@ SGSubsystemMgr::SGSubsystemMgr ()
SGSubsystemMgr::~SGSubsystemMgr () SGSubsystemMgr::~SGSubsystemMgr ()
{ {
// ensure get_subsystem returns NULL from now onwards,
// before the SGSubsystemGroup destructors are run
_subsystem_map.clear();
} }
void void
@@ -475,6 +478,29 @@ SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
_subsystem_map[name] = 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 * SGSubsystemGroup *
SGSubsystemMgr::get_group (GroupType group) SGSubsystemMgr::get_group (GroupType group)
{ {
@@ -482,9 +508,9 @@ SGSubsystemMgr::get_group (GroupType group)
} }
SGSubsystem * SGSubsystem *
SGSubsystemMgr::get_subsystem (const string &name) SGSubsystemMgr::get_subsystem (const string &name) const
{ {
map<string,SGSubsystem *>::iterator s =_subsystem_map.find(name); SubsystemDict::const_iterator s =_subsystem_map.find(name);
if (s == _subsystem_map.end()) if (s == _subsystem_map.end())
return 0; return 0;
+23 -19
View File
@@ -29,10 +29,6 @@
#include <map> #include <map>
#include <vector> #include <vector>
using std::map;
using std::vector;
using std::string;
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/timing/timestamp.hxx> #include <simgear/timing/timestamp.hxx>
#include "SGSmplstat.hxx" #include "SGSmplstat.hxx"
@@ -41,19 +37,19 @@ using std::string;
class TimingInfo class TimingInfo
{ {
private: private:
string eventName; std::string eventName;
SGTimeStamp time; SGTimeStamp time;
public: public:
TimingInfo(const string& name, const SGTimeStamp &t) : TimingInfo(const std::string& name, const SGTimeStamp &t) :
eventName(name), time(t) eventName(name), time(t)
{ } { }
const string& getName() const { return eventName; } const std::string& getName() const { return eventName; }
const SGTimeStamp& getTime() const { return time; } const SGTimeStamp& getTime() const { return time; }
}; };
typedef vector<TimingInfo> eventTimeVec; typedef std::vector<TimingInfo> eventTimeVec;
typedef vector<TimingInfo>::iterator eventTimeVecIterator; typedef std::vector<TimingInfo>::iterator eventTimeVecIterator;
@@ -273,7 +269,7 @@ public:
* Place time stamps at strategic points in the execution of subsystems * Place time stamps at strategic points in the execution of subsystems
* update() member functions. Predominantly for debugging purposes. * 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 void resume ();
virtual bool is_suspended () const; virtual bool is_suspended () const;
virtual void set_subsystem (const string &name, virtual void set_subsystem (const std::string &name,
SGSubsystem * subsystem, SGSubsystem * subsystem,
double min_step_sec = 0); double min_step_sec = 0);
virtual SGSubsystem * get_subsystem (const string &name); virtual SGSubsystem * get_subsystem (const std::string &name);
virtual void remove_subsystem (const string &name); virtual void remove_subsystem (const std::string &name);
virtual bool has_subsystem (const string &name) const; virtual bool has_subsystem (const std::string &name) const;
void collectDebugTiming(bool collect); void collectDebugTiming(bool collect);
@@ -339,7 +335,7 @@ private:
void collectDebugTiming (bool collect) { collectTimeStats = collect; }; void collectDebugTiming (bool collect) { collectTimeStats = collect; };
SampleStatistic timeStat; SampleStatistic timeStat;
string name; std::string name;
SGSubsystem * subsystem; SGSubsystem * subsystem;
double min_step_sec; double min_step_sec;
double elapsed_sec; double elapsed_sec;
@@ -347,9 +343,9 @@ private:
int exceptionCount; int exceptionCount;
}; };
Member * get_member (const string &name, bool create = false); Member * get_member (const std::string &name, bool create = false);
vector<Member *> _members; std::vector<Member *> _members;
double _fixedUpdateTime; double _fixedUpdateTime;
double _updateTimeRemainder; double _updateTimeRemainder;
@@ -408,16 +404,24 @@ public:
GroupType group = GENERAL, GroupType group = GENERAL,
double min_time_sec = 0); 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 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); void collectDebugTiming(bool collect);
private: private:
SGSubsystemGroup _groups[MAX_GROUPS]; SGSubsystemGroup _groups[MAX_GROUPS];
map<string,SGSubsystem *> _subsystem_map;
typedef std::map<std::string, SGSubsystem*> SubsystemDict;
SubsystemDict _subsystem_map;
}; };