diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2015-09-14 08:33:28 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2015-09-14 08:33:28 +0200 |
commit | fa1e1ebca142e5256d50247ef13dc5efc56c6346 (patch) | |
tree | e00372cf9a12609ae5637b5df468374e365da493 /src/RemoteControl.h | |
parent | 43887597d457488d725897186ca51fd52ab1a139 (diff) | |
download | dabmod-fa1e1ebca142e5256d50247ef13dc5efc56c6346.tar.gz dabmod-fa1e1ebca142e5256d50247ef13dc5efc56c6346.tar.bz2 dabmod-fa1e1ebca142e5256d50247ef13dc5efc56c6346.zip |
Fix crash when using RC after a mod restart
Diffstat (limited to 'src/RemoteControl.h')
-rw-r--r-- | src/RemoteControl.h | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/src/RemoteControl.h b/src/RemoteControl.h index 8c3362c..deae961 100644 --- a/src/RemoteControl.h +++ b/src/RemoteControl.h @@ -79,6 +79,9 @@ class BaseRemoteController { /* Add a new controllable under this controller's command */ virtual void enrol(RemoteControllable* controllable) = 0; + /* Remove a controllable under this controller's command */ + virtual void disengage(RemoteControllable* controllable) = 0; + /* When this returns one, the remote controller cannot be * used anymore, and must be restarted by dabmux */ @@ -107,6 +110,12 @@ class RemoteControllers { } } + void remove_controllable(RemoteControllable *rc) { + for (auto &controller : m_controllers) { + controller->disengage(rc); + } + } + void check_faults() { for (auto &controller : m_controllers) { if (controller->fault_detected()) @@ -127,9 +136,15 @@ class RemoteControllers { class RemoteControllable { public: - RemoteControllable(std::string name) : m_name(name) {} + RemoteControllable(std::string name) : + m_rcs_enrolled_at(nullptr), + m_name(name) {} - virtual ~RemoteControllable() {} + virtual ~RemoteControllable() { + if (m_rcs_enrolled_at) { + m_rcs_enrolled_at->remove_controllable(this); + } + } /* return a short name used to identify the controllable. * It might be used in the commands the user has to type, so keep @@ -139,6 +154,11 @@ class RemoteControllable { /* Tell the controllable to enrol at the given controller */ virtual void enrol_at(RemoteControllers& controllers) { + if (m_rcs_enrolled_at) { + throw std::runtime_error("This controllable is already enrolled"); + } + + m_rcs_enrolled_at = &controllers; controllers.add_controllable(this); } @@ -165,8 +185,12 @@ class RemoteControllable { virtual const std::string get_parameter(const std::string& parameter) const = 0; protected: + RemoteControllers* m_rcs_enrolled_at; std::string m_name; std::list< std::vector<std::string> > m_parameters; + + RemoteControllable(const RemoteControllable& other) = delete; + RemoteControllable& operator=(const RemoteControllable& other) = delete; }; /* Implements a Remote controller based on a simple telnet CLI @@ -197,6 +221,10 @@ class RemoteControllerTelnet : public BaseRemoteController { m_cohort.push_back(controllable); } + void disengage(RemoteControllable* controllable) { + m_cohort.remove(controllable); + } + virtual bool fault_detected() { return m_fault; } virtual void restart(); @@ -316,6 +344,10 @@ class RemoteControllerZmq : public BaseRemoteController { m_cohort.push_back(controllable); } + void disengage(RemoteControllable* controllable) { + m_cohort.remove(controllable); + } + virtual bool fault_detected() { return m_fault; } virtual void restart(); @@ -392,6 +424,7 @@ class RemoteControllerZmq : public BaseRemoteController { class RemoteControllerDummy : public BaseRemoteController { public: void enrol(RemoteControllable*) {} + void disengage(RemoteControllable*) {} bool fault_detected() { return false; } |