aboutsummaryrefslogtreecommitdiffstats
path: root/src/RemoteControl.h
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2015-09-14 08:33:28 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2015-09-14 08:33:28 +0200
commitfa1e1ebca142e5256d50247ef13dc5efc56c6346 (patch)
treee00372cf9a12609ae5637b5df468374e365da493 /src/RemoteControl.h
parent43887597d457488d725897186ca51fd52ab1a139 (diff)
downloaddabmod-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.h37
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; }