aboutsummaryrefslogtreecommitdiffstats
path: root/src/RemoteControl.h
diff options
context:
space:
mode:
authorKenneth Mortensen <mortensenit@users.noreply.github.com>2015-04-22 11:39:19 +0200
committerKenneth Mortensen <mortensenit@users.noreply.github.com>2015-04-22 11:39:19 +0200
commitd45f9b924c54fc40c228b8d3709e93fed7720705 (patch)
tree1192e317e6fdfae692f67843400b698c49ee7a1f /src/RemoteControl.h
parent191817b42ad86a250bbff02895e9646f51531672 (diff)
parent81775f47227c5d08a05b43ffb3855bff0a237c1d (diff)
downloaddabmod-d45f9b924c54fc40c228b8d3709e93fed7720705.tar.gz
dabmod-d45f9b924c54fc40c228b8d3709e93fed7720705.tar.bz2
dabmod-d45f9b924c54fc40c228b8d3709e93fed7720705.zip
Merge remote-tracking branch 'upstream/master'
Conflicts: src/InputFileReader.cpp
Diffstat (limited to 'src/RemoteControl.h')
-rw-r--r--src/RemoteControl.h127
1 files changed, 125 insertions, 2 deletions
diff --git a/src/RemoteControl.h b/src/RemoteControl.h
index 09e7492..89a1583 100644
--- a/src/RemoteControl.h
+++ b/src/RemoteControl.h
@@ -29,6 +29,14 @@
#ifndef _REMOTECONTROL_H
#define _REMOTECONTROL_H
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if defined(HAVE_ZEROMQ)
+#include <zmq.hpp>
+#endif
+
#include <list>
#include <map>
#include <string>
@@ -85,6 +93,39 @@ class BaseRemoteController {
virtual ~BaseRemoteController() {}
};
+/* Holds all our remote controllers, i.e. we may have more than
+ * one type of controller running.
+ */
+class RemoteControllers {
+ public:
+ void add_controller(BaseRemoteController *rc) {
+ m_controllers.push_back(rc);
+ }
+
+ void add_controllable(RemoteControllable *rc) {
+ for (std::list<BaseRemoteController*>::iterator it = m_controllers.begin();
+ it != m_controllers.end(); ++it) {
+ (*it)->enrol(rc);
+ }
+ }
+
+ void check_faults() {
+ for (std::list<BaseRemoteController*>::iterator it = m_controllers.begin();
+ it != m_controllers.end(); ++it) {
+ if ((*it)->fault_detected())
+ {
+ fprintf(stderr,
+ "Detected Remote Control fault, restarting it\n");
+ (*it)->restart();
+ }
+ }
+ }
+ size_t get_no_controllers() { return m_controllers.size(); }
+
+ private:
+ std::list<BaseRemoteController*> m_controllers;
+};
+
/* Objects that support remote control must implement the following class */
class RemoteControllable {
public:
@@ -100,8 +141,8 @@ class RemoteControllable {
virtual std::string get_rc_name() const { return m_name; }
/* Tell the controllable to enrol at the given controller */
- virtual void enrol_at(BaseRemoteController& controller) {
- controller.enrol(this);
+ virtual void enrol_at(RemoteControllers& controllers) {
+ controllers.add_controllable(this);
}
/* Return a list of possible parameters that can be set */
@@ -254,6 +295,88 @@ class RemoteControllerTelnet : public BaseRemoteController {
int m_port;
};
+#if defined(HAVE_ZEROMQ)
+/* Implements a Remote controller using zmq transportlayer
+ * that listens on localhost
+ */
+class RemoteControllerZmq : public BaseRemoteController {
+ public:
+ RemoteControllerZmq()
+ : m_running(false), m_fault(false),
+ m_zmqContext(1),
+ m_endpoint("") { }
+
+ RemoteControllerZmq(std::string endpoint)
+ : m_running(true), m_fault(false),
+ m_child_thread(&RemoteControllerZmq::process, this),
+ m_zmqContext(1),
+ m_endpoint(endpoint) { }
+
+ ~RemoteControllerZmq() {
+ m_running = false;
+ m_fault = false;
+ if (!m_endpoint.empty()) {
+ m_child_thread.interrupt();
+ m_child_thread.join();
+ }
+ }
+
+ void enrol(RemoteControllable* controllable) {
+ m_cohort.push_back(controllable);
+ }
+
+ virtual bool fault_detected() { return m_fault; }
+
+ virtual void restart();
+
+ private:
+ void restart_thread();
+
+ void recv_all(zmq::socket_t* pSocket, std::vector<std::string> &message);
+ void send_ok_reply(zmq::socket_t *pSocket);
+ void send_fail_reply(zmq::socket_t *pSocket, const std::string &error);
+ void process();
+
+
+ RemoteControllerZmq& operator=(const RemoteControllerZmq& other);
+ RemoteControllerZmq(const RemoteControllerZmq& other);
+
+ RemoteControllable* get_controllable_(std::string name) {
+ for (std::list<RemoteControllable*>::iterator it = m_cohort.begin();
+ it != m_cohort.end(); ++it) {
+ if ((*it)->get_rc_name() == name)
+ {
+ return *it;
+ }
+ }
+ throw ParameterError("Module name unknown");
+ }
+
+ std::string get_param_(std::string name, std::string param) {
+ RemoteControllable* controllable = get_controllable_(name);
+ return controllable->get_parameter(param);
+ }
+
+ void set_param_(std::string name, std::string param, std::string value) {
+ RemoteControllable* controllable = get_controllable_(name);
+ return controllable->set_parameter(param, value);
+ }
+
+ bool m_running;
+
+ /* This is set to true if a fault occurred */
+ bool m_fault;
+ boost::thread m_restarter_thread;
+
+ boost::thread m_child_thread;
+
+ /* This controller commands the controllables in the cohort */
+ std::list<RemoteControllable*> m_cohort;
+
+ zmq::context_t m_zmqContext;
+ std::string m_endpoint;
+};
+#endif
/* The Dummy remote controller does nothing, and never fails
*/