diff options
| -rw-r--r-- | Makefile.am | 28 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | lib/ClockTAI.cpp (renamed from src/ClockTAI.cpp) | 2 | ||||
| -rw-r--r-- | lib/ClockTAI.h (renamed from src/ClockTAI.h) | 4 | ||||
| -rw-r--r-- | lib/Log.cpp (renamed from src/Log.cpp) | 91 | ||||
| -rw-r--r-- | lib/Log.h (renamed from src/Log.h) | 63 | ||||
| -rw-r--r-- | lib/ReedSolomon.cpp | 4 | ||||
| -rw-r--r-- | lib/RemoteControl.cpp (renamed from src/RemoteControl.cpp) | 132 | ||||
| -rw-r--r-- | lib/RemoteControl.h (renamed from src/RemoteControl.h) | 46 | ||||
| -rw-r--r-- | lib/crc.c (renamed from src/crc.c) | 0 | ||||
| -rw-r--r-- | lib/crc.h (renamed from src/crc.h) | 0 | 
11 files changed, 222 insertions, 150 deletions
| diff --git a/Makefile.am b/Makefile.am index 6e5aa71..216f7c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -94,25 +94,17 @@ odr_dabmux_SOURCES  =src/DabMux.cpp \  					 src/dabOutput/edi/TagPacket.h \  					 src/dabOutput/edi/Transport.cpp \  					 src/dabOutput/edi/Transport.h \ -					 src/ClockTAI.h \ -					 src/ClockTAI.cpp \  					 src/ConfigParser.cpp \  					 src/ConfigParser.h \  					 src/Eti.h \  					 src/Eti.cpp \  					 src/Interleaver.h \  					 src/Interleaver.cpp \ -					 src/Log.h \ -					 src/Log.cpp \  					 src/ManagementServer.h \  					 src/ManagementServer.cpp \  					 src/MuxElements.cpp \  					 src/MuxElements.h \  					 src/PcDebug.h \ -					 src/RemoteControl.cpp \ -					 src/RemoteControl.h \ -					 src/crc.h \ -					 src/crc.c \  					 src/fig/FIG.h \  					 src/fig/FIG.cpp \  					 src/fig/FIG0.h \ @@ -160,6 +152,14 @@ odr_dabmux_SOURCES  =src/DabMux.cpp \  					 src/PrbsGenerator.h \  					 src/utils.cpp \  					 src/utils.h \ +					 lib/crc.h \ +					 lib/crc.c \ +					 lib/ClockTAI.h \ +					 lib/ClockTAI.cpp \ +					 lib/Log.h \ +					 lib/Log.cpp \ +					 lib/RemoteControl.cpp \ +					 lib/RemoteControl.h \  					 lib/edi/STIDecoder.cpp \  					 lib/edi/STIDecoder.h \  					 lib/edi/STIWriter.cpp \ @@ -185,8 +185,8 @@ zmqinput_keygen_CFLAGS   = -Wall $(GITVERSION_FLAGS) $(ZMQ_CPPFLAGS)  odr_zmq2farsync_SOURCES  = src/zmq2farsync/zmq2farsync.cpp \  						   src/dabOutput/dabOutput.h \  						   src/dabOutput/dabOutputRaw.cpp \ -						   src/Log.h \ -						   src/Log.cpp \ +						   lib/Log.h \ +						   lib/Log.cpp \  						   lib/zmq.hpp  odr_zmq2farsync_LDADD    = $(ZMQ_LIBS) @@ -212,10 +212,10 @@ odr_zmq2edi_SOURCES  = src/zmq2edi/zmq2edi.cpp \  					   src/dabOutput/edi/TagPacket.h \  					   src/dabOutput/edi/Transport.cpp \  					   src/dabOutput/edi/Transport.h \ -					   src/Log.h \ -					   src/Log.cpp \ -					   src/crc.h \ -					   src/crc.c \ +					   lib/Log.h \ +					   lib/Log.cpp \ +					   lib/crc.h \ +					   lib/crc.c \  					   lib/ReedSolomon.h \  					   lib/ReedSolomon.cpp \  					   lib/Socket.h \ diff --git a/configure.ac b/configure.ac index 50623a2..405b6f0 100644 --- a/configure.ac +++ b/configure.ac @@ -128,7 +128,7 @@ AX_ZMQ([4.0.0], [], AC_MSG_ERROR(ZeroMQ 4.0.0 is required))  AC_DEFINE([HAVE_INPUT_ZEROMQ], [1], [Define if ZeroMQ input is enabled])  AC_DEFINE([HAVE_OUTPUT_ZEROMQ], [1], [Define if ZeroMQ output is enabled]) -AC_DEFINE([HAVE_RC_ZEROMQ], [1], [Define if ZeroMQ enabled for rc]) +AC_DEFINE([HAVE_ZEROMQ], [1], [Define if ZeroMQ enabled for rc])  # Do not build odr-zmq2farsync if no RAW output  AM_CONDITIONAL([HAVE_OUTPUT_RAW_TEST], diff --git a/src/ClockTAI.cpp b/lib/ClockTAI.cpp index c376c07..42497f4 100644 --- a/src/ClockTAI.cpp +++ b/lib/ClockTAI.cpp @@ -477,7 +477,7 @@ void ClockTAI::set_parameter(const string& parameter, const string& value)  {      if (parameter == "expiry") {          throw ParameterError("Parameter '" + parameter + -            "' is not read-only in controllable " + get_rc_name()); +            "' is read-only in controllable " + get_rc_name());      }      else {          throw ParameterError("Parameter '" + parameter + diff --git a/src/ClockTAI.h b/lib/ClockTAI.h index 4b3c2ff..bb85815 100644 --- a/src/ClockTAI.h +++ b/lib/ClockTAI.h @@ -34,8 +34,8 @@  #pragma once -#include <stdint.h> -#include <stdlib.h> +#include <cstdint> +#include <cstdlib>  #include <sstream>  #include <chrono>  #include <future> diff --git a/src/Log.cpp b/lib/Log.cpp index 6b78fe0..2417f3a 100644 --- a/src/Log.cpp +++ b/lib/Log.cpp @@ -9,31 +9,32 @@      http://www.opendigitalradio.org   */  /* -   This file is part of ODR-DabMux. +   This file is part of the ODR-mmbTools. -   ODR-DabMux is free software: you can redistribute it and/or modify +   This program is free software: you can redistribute it and/or modify     it under the terms of the GNU General Public License as     published by the Free Software Foundation, either version 3 of the     License, or (at your option) any later version. -   ODR-DabMux is distributed in the hope that it will be useful, +   This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     GNU General Public License for more details.     You should have received a copy of the GNU General Public License -   along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  #include <list>  #include <cstdarg> +#include <cinttypes>  #include <chrono>  #include "Log.h"  using namespace std; -/* etiLog is a singleton used in all parts of ODR-DabMod to output log messages. +/* etiLog is a singleton used in all parts of the program to output log messages.   */  Logger etiLog; @@ -74,22 +75,40 @@ void Logger::logstr(log_level_t level, std::string&& message)  {      if (level == discard) {          return; -    } +	} -    /* Remove a potential trailing newline. -     * It doesn't look good in syslog -     */ -    if (message[message.length()-1] == '\n') { -        message.resize(message.length()-1); -    } +    log_message_t m(level, move(message)); +    m_message_queue.push(move(m)); +} -    for (auto &backend : backends) { -        backend->log(level, message); -    } +void Logger::io_process() +{ +    while (1) { +        log_message_t m; +        try { +            m_message_queue.wait_and_pop(m); +        } +        catch (const ThreadsafeQueueWakeup&) { +            break; +        } + +        auto message = m.message; + +        /* Remove a potential trailing newline. +         * It doesn't look good in syslog +         */ +        if (message[message.length()-1] == '\n') { +            message.resize(message.length()-1); +        } + +        for (auto &backend : backends) { +            backend->log(m.level, message); +        } -    { -        std::lock_guard<std::mutex> guard(m_cerr_mutex); -        std::cerr << levels_as_str[level] << " " << message << std::endl; +        if (m.level != log_level_t::trace) { +            std::lock_guard<std::mutex> guard(m_cerr_mutex); +            std::cerr << levels_as_str[m.level] << " " << message << std::endl; +        }      }  } @@ -112,7 +131,7 @@ LogToFile::LogToFile(const std::string& filename) : name("FILE")  void LogToFile::log(log_level_t level, const std::string& message)  { -    if (level != log_level_t::discard) { +    if (not (level == log_level_t::trace or level == log_level_t::discard)) {          const char* log_level_text[] = {              "DEBUG", "INFO", "WARN", "ERROR", "ALERT", "EMERG"}; @@ -125,7 +144,7 @@ void LogToFile::log(log_level_t level, const std::string& message)  void LogToSyslog::log(log_level_t level, const std::string& message)  { -    if (level != log_level_t::discard) { +    if (not (level == log_level_t::trace or level == log_level_t::discard)) {          int syslog_level = LOG_EMERG;          switch (level) {              case debug: syslog_level = LOG_DEBUG; break; @@ -141,3 +160,35 @@ void LogToSyslog::log(log_level_t level, const std::string& message)          syslog(syslog_level, SYSLOG_IDENT " %s", message.c_str());      }  } + +LogTracer::LogTracer(const string& trace_filename) : name("TRACE") +{ +    etiLog.level(info) << "Setting up TRACE to " << trace_filename; + +    FILE* fd = fopen(trace_filename.c_str(), "a"); +    if (fd == nullptr) { +        fprintf(stderr, "Cannot open trace file !"); +        throw std::runtime_error("Cannot open trace file !"); +    } +    m_trace_file.reset(fd); + +    using namespace std::chrono; +    auto now = steady_clock::now().time_since_epoch(); +    m_trace_micros_startup = duration_cast<microseconds>(now).count(); + +    fprintf(m_trace_file.get(), +            "0,TRACER,startup at %" PRIu64 "\n", m_trace_micros_startup); +} + +void LogTracer::log(log_level_t level, const std::string& message) +{ +    if (level == log_level_t::trace) { +        using namespace std::chrono; +        const auto now = steady_clock::now().time_since_epoch(); +        const auto micros = duration_cast<microseconds>(now).count(); + +        fprintf(m_trace_file.get(), "%" PRIu64 ",%s\n", +                micros - m_trace_micros_startup, +                message.c_str()); +    } +} @@ -9,20 +9,20 @@      http://www.opendigitalradio.org   */  /* -   This file is part of ODR-DabMux. +   This file is part of the ODR-mmbTools. -   ODR-DabMux is free software: you can redistribute it and/or modify +   This program is free software: you can redistribute it and/or modify     it under the terms of the GNU General Public License as     published by the Free Software Foundation, either version 3 of the     License, or (at your option) any later version. -   ODR-DabMux is distributed in the hope that it will be useful, +   This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     GNU General Public License for more details.     You should have received a copy of the GNU General Public License -   along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  #pragma once @@ -40,16 +40,19 @@  #include <list>  #include <stdexcept>  #include <string> +#include <map>  #include <mutex>  #include <memory> +#include <thread> +#include "ThreadsafeQueue.h" -#define SYSLOG_IDENT "ODR-DabMux" +#define SYSLOG_IDENT PACKAGE_NAME  #define SYSLOG_FACILITY LOG_LOCAL0 -enum log_level_t {debug = 0, info, warn, error, alert, emerg, discard}; +enum log_level_t {debug = 0, info, warn, error, alert, emerg, trace, discard};  static const std::string levels_as_str[] = -    { "     ", "     ", "WARN ", "ERROR", "ALERT", "EMERG", "-----"} ; +    { "     ", "     ", "WARN ", "ERROR", "ALERT", "EMERG", "TRACE", "-----"} ;  /** Abstract class all backends must inherit from */  class LogBackend { @@ -97,10 +100,50 @@ class LogToFile : public LogBackend {          const LogToFile& operator=(const LogToFile& other) = delete;  }; +class LogTracer : public LogBackend { +    public: +        LogTracer(const std::string& filename); +        void log(log_level_t level, const std::string& message); +        std::string get_name() const { return name; } +    private: +        std::string name; +        uint64_t m_trace_micros_startup = 0; + +        struct FILEDeleter{ void operator()(FILE* fd){ if(fd) fclose(fd);}}; +        std::unique_ptr<FILE, FILEDeleter> m_trace_file; + +        LogTracer(const LogTracer& other) = delete; +        const LogTracer& operator=(const LogTracer& other) = delete; +}; +  class LogLine; +struct log_message_t { +    log_message_t(log_level_t _level, std::string&& _message) : +        level(_level), +        message(move(_message)) {} + +    log_message_t() : +        level(debug), +        message("") {} + +    log_level_t level; +    std::string message; +}; +  class Logger {      public: +        Logger() { +            m_io_thread = std::thread(&Logger::io_process, this); +        } + +        Logger(const Logger& other) = delete; +        const Logger& operator=(const Logger& other) = delete; +        ~Logger() { +            m_message_queue.trigger_wakeup(); +            m_io_thread.join(); +        } +          void register_backend(std::shared_ptr<LogBackend> backend);          /* Log the message to all backends */ @@ -108,6 +151,9 @@ class Logger {          void logstr(log_level_t level, std::string&& message); +        /* All logging IO is done in another thread */ +        void io_process(void); +          /* Return a LogLine for the given level           * so that you can write etiLog.level(info) << "stuff = " << 21 */          LogLine level(log_level_t level); @@ -115,6 +161,8 @@ class Logger {      private:          std::list<std::shared_ptr<LogBackend> > backends; +        ThreadsafeQueue<log_message_t> m_message_queue; +        std::thread m_io_thread;          std::mutex m_cerr_mutex;  }; @@ -154,4 +202,3 @@ class LogLine {          Logger* logger_;  }; - diff --git a/lib/ReedSolomon.cpp b/lib/ReedSolomon.cpp index 38d8ea8..1bf0b24 100644 --- a/lib/ReedSolomon.cpp +++ b/lib/ReedSolomon.cpp @@ -64,7 +64,9 @@ ReedSolomon::ReedSolomon(int N, int K, bool reverse, int gfpoly, int firstRoot,  ReedSolomon::~ReedSolomon()  { -    free_rs_char(rsData); +    if (rsData != nullptr) { +        free_rs_char(rsData); +    }  } diff --git a/src/RemoteControl.cpp b/lib/RemoteControl.cpp index b32c21a..878af59 100644 --- a/src/RemoteControl.cpp +++ b/lib/RemoteControl.cpp @@ -9,31 +9,27 @@      http://www.opendigitalradio.org   */  /* -   This file is part of ODR-DabMux. +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. -   ODR-DabMux is free software: you can redistribute it and/or modify -   it under the terms of the GNU General Public License as -   published by the Free Software Foundation, either version 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux is distributed in the hope that it will be useful, +   This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     GNU General Public License for more details.     You should have received a copy of the GNU General Public License -   along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   along with this program.  If not, see <https://www.gnu.org/licenses/>.   */  #include <list>  #include <string>  #include <iostream>  #include <string> -#include <boost/asio.hpp> -#include <boost/thread.hpp> +#include <algorithm>  #include "RemoteControl.h" -using boost::asio::ip::tcp;  using namespace std;  RemoteControllers rcs; @@ -41,7 +37,6 @@ RemoteControllers rcs;  RemoteControllerTelnet::~RemoteControllerTelnet()  {      m_active = false; -    m_io_service.stop();      if (m_restarter_thread.joinable()) {          m_restarter_thread.join(); @@ -158,7 +153,6 @@ void RemoteControllers::set_param(  void RemoteControllerTelnet::restart_thread(long)  {      m_active = false; -    m_io_service.stop();      if (m_child_thread.joinable()) {          m_child_thread.join(); @@ -167,52 +161,56 @@ void RemoteControllerTelnet::restart_thread(long)      m_child_thread = std::thread(&RemoteControllerTelnet::process, this, 0);  } -void RemoteControllerTelnet::handle_accept( -        const boost::system::error_code& boost_error, -        boost::shared_ptr< boost::asio::ip::tcp::socket > socket, -        boost::asio::ip::tcp::acceptor& acceptor) +void RemoteControllerTelnet::handle_accept(Socket::TCPSocket&& socket)  { - -    const std::string welcome = "ODR-DabMux Remote Control CLI\n" +    const std::string welcome = PACKAGE_NAME " Remote Control CLI\n"                                  "Write 'help' for help.\n"                                  "**********\n";      const std::string prompt = "> ";      std::string in_message; -    size_t length; - -    if (boost_error) { -        etiLog.level(error) << "RC: Error accepting connection"; -        return; -    }      try {          etiLog.level(info) << "RC: Accepted"; -        boost::system::error_code ignored_error; +        socket.sendall(welcome.data(), welcome.size()); -        boost::asio::write(*socket, boost::asio::buffer(welcome), -                boost::asio::transfer_all(), -                ignored_error); +        while (m_active and in_message != "quit") { +            socket.sendall(prompt.data(), prompt.size()); -        while (m_active && in_message != "quit") { -            boost::asio::write(*socket, boost::asio::buffer(prompt), -                    boost::asio::transfer_all(), -                    ignored_error); +            stringstream in_message_stream; -            in_message = ""; - -            boost::asio::streambuf buffer; -            length = boost::asio::read_until(*socket, buffer, "\n", ignored_error); +            char last_char = '\0'; +            try { +                while (last_char != '\n') { +                    try { +                        auto ret = socket.recv(&last_char, 1, 0, 1000); +                        if (ret == 1) { +                            in_message_stream << last_char; +                        } +                        else { +                            break; +                        } +                    } +                    catch (const Socket::TCPSocket::Timeout&) { +                        if (not m_active) { +                            break; +                        } +                    } +                } +            } +            catch (const Socket::TCPSocket::Interrupted&) { +                in_message_stream.clear(); +            } -            std::istream str(&buffer); -            std::getline(str, in_message); -            if (length == 0) { +            if (in_message_stream.str().size() == 0) {                  etiLog.level(info) << "RC: Connection terminated";                  break;              } +            std::getline(in_message_stream, in_message); +              while (in_message.length() > 0 &&                      (in_message[in_message.length()-1] == '\r' ||                       in_message[in_message.length()-1] == '\n')) { @@ -225,44 +223,35 @@ void RemoteControllerTelnet::handle_accept(              etiLog.level(info) << "RC: Got message '" << in_message << "'"; -            dispatch_command(*socket, in_message); +            dispatch_command(socket, in_message);          }          etiLog.level(info) << "RC: Closing socket"; -        socket->close(); +        socket.close();      } -    catch (const std::exception& e) -    { +    catch (const std::exception& e) {          etiLog.level(error) << "Remote control caught exception: " << e.what();      }  }  void RemoteControllerTelnet::process(long)  { -    m_active = true; - -    while (m_active) { -        m_io_service.reset(); - -        tcp::acceptor acceptor(m_io_service, tcp::endpoint( -                    boost::asio::ip::address::from_string("127.0.0.1"), m_port) ); - +    try { +        m_active = true; -        // Add a job to start accepting connections. -        boost::shared_ptr<tcp::socket> socket( -                new tcp::socket(acceptor.get_io_service())); +        m_socket.listen(m_port, "localhost"); -        // Add an accept call to the service.  This will prevent io_service::run() -        // from returning.          etiLog.level(info) << "RC: Waiting for connection on port " << m_port; -        acceptor.async_accept(*socket, -                boost::bind(&RemoteControllerTelnet::handle_accept, -                    this, -                    boost::asio::placeholders::error, -                    socket, -                    boost::ref(acceptor))); - -        // Process event loop. -        m_io_service.run(); +        while (m_active) { +            auto sock = m_socket.accept(1000); + +            if (sock.valid()) { +                handle_accept(move(sock)); +                etiLog.level(info) << "RC: Connection closed. Waiting for connection on port " << m_port; +            } +        } +    } +    catch (const runtime_error& e) { +        etiLog.level(warn) << "RC: Encountered error: " << e.what();      }      etiLog.level(info) << "RC: Leaving"; @@ -281,7 +270,7 @@ static std::vector<std::string> tokenise(const std::string& message) {  } -void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string command) +void RemoteControllerTelnet::dispatch_command(Socket::TCPSocket& socket, string command)  {      vector<string> cmd = tokenise(command); @@ -386,18 +375,15 @@ void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string comman      }  } -void RemoteControllerTelnet::reply(tcp::socket& socket, string message) +void RemoteControllerTelnet::reply(Socket::TCPSocket& socket, string message)  { -    boost::system::error_code ignored_error;      stringstream ss;      ss << message << "\r\n"; -    boost::asio::write(socket, boost::asio::buffer(ss.str()), -            boost::asio::transfer_all(), -            ignored_error); +    socket.sendall(message.data(), message.size());  } -#if defined(HAVE_RC_ZEROMQ) +#if defined(HAVE_ZEROMQ)  RemoteControllerZmq::~RemoteControllerZmq() {      m_active = false; diff --git a/src/RemoteControl.h b/lib/RemoteControl.h index 0726b28..bd88f82 100644 --- a/src/RemoteControl.h +++ b/lib/RemoteControl.h @@ -8,23 +8,21 @@      http://www.opendigitalradio.org -   This module adds remote-control capability to some of the dabmux modules. +   This module adds remote-control capability to some of the dabmux/dabmod modules.   */  /* -   This file is part of ODR-DabMux. +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. -   ODR-DabMux is free software: you can redistribute it and/or modify -   it under the terms of the GNU General Public License as -   published by the Free Software Foundation, either version 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux is distributed in the hope that it will be useful, +   This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     GNU General Public License for more details.     You should have received a copy of the GNU General Public License -   along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   along with this program.  If not, see <https://www.gnu.org/licenses/>.   */  #pragma once @@ -33,7 +31,7 @@  #  include "config.h"  #endif -#if defined(HAVE_RC_ZEROMQ) +#if defined(HAVE_ZEROMQ)  #  include "zmq.hpp"  #endif @@ -43,14 +41,11 @@  #include <string>  #include <atomic>  #include <iostream> -#include <boost/bind.hpp> -#include <boost/asio.hpp> -#include <boost/foreach.hpp> -#include <boost/tokenizer.hpp>  #include <thread>  #include <stdexcept>  #include "Log.h" +#include "Socket.h"  #define RC_ADD_PARAMETER(p, desc) {   \    std::vector<std::string> p; \ @@ -78,7 +73,7 @@ class RemoteControllable;  class BaseRemoteController {      public:          /* When this returns one, the remote controller cannot be -         * used anymore, and must be restarted by dabmux +         * used anymore, and must be restarted           */          virtual bool fault_detected() = 0; @@ -163,13 +158,11 @@ class RemoteControllerTelnet : public BaseRemoteController {      public:          RemoteControllerTelnet()              : m_active(false), -            m_io_service(),              m_fault(false),              m_port(0) { }          RemoteControllerTelnet(int port)              : m_active(port > 0), -            m_io_service(),              m_fault(false),              m_port(port)          { @@ -191,31 +184,24 @@ class RemoteControllerTelnet : public BaseRemoteController {          void process(long); -        void dispatch_command(boost::asio::ip::tcp::socket& socket, -                std::string command); - -        void reply(boost::asio::ip::tcp::socket& socket, std::string message); - -        void handle_accept( -                const boost::system::error_code& boost_error, -                boost::shared_ptr< boost::asio::ip::tcp::socket > socket, -                boost::asio::ip::tcp::acceptor& acceptor); +        void dispatch_command(Socket::TCPSocket& socket, std::string command); +        void reply(Socket::TCPSocket& socket, std::string message); +        void handle_accept(Socket::TCPSocket&& socket);          std::atomic<bool> m_active; -        boost::asio::io_service m_io_service; -          /* This is set to true if a fault occurred */          std::atomic<bool> m_fault;          std::thread m_restarter_thread;          std::thread m_child_thread; +        Socket::TCPSocket m_socket;          int m_port;  }; -#if defined(HAVE_RC_ZEROMQ) -/* Implements a Remote controller using zmq transportlayer +#if defined(HAVE_ZEROMQ) +/* Implements a Remote controller using ZMQ transportlayer   * that listens on localhost   */  class RemoteControllerZmq : public BaseRemoteController { | 
