From fa1e1ebca142e5256d50247ef13dc5efc56c6346 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 14 Sep 2015 08:33:28 +0200 Subject: Fix crash when using RC after a mod restart --- src/DabModulator.cpp | 2 +- src/RemoteControl.h | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index f55d918..e0e2bad 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -70,7 +70,7 @@ DabModulator::DabModulator( myGainMode(gainMode), myDigGain(digGain), myNormalise(normalise), - myEtiReader(EtiReader(tist_offset_s, tist_delay_stages, rcs)), + myEtiReader(tist_offset_s, tist_delay_stages, rcs), myFlowgraph(NULL), myFilterTapsFilename(filterTapsFilename), myTiiConfig(tiiConfig), 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 > 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; } -- cgit v1.2.3