From b18842308f2d5412c5098a518a777cd484015df1 Mon Sep 17 00:00:00 2001 From: BenDroid Date: Tue, 14 Nov 2017 23:22:30 +0100 Subject: [PATCH] Moved CCClient to seperate thrad and process ControlCommands async --- src/App.cpp | 30 ++++++++++++++++++++--- src/App.h | 4 +++- src/cc/CCClient.cpp | 53 ++++++++++++++++++++++++----------------- src/cc/CCClient.h | 8 +++++-- src/cc/ClientStatus.cpp | 14 ++++++++++- src/cc/ControlCommand.h | 20 ++++++++-------- 6 files changed, 90 insertions(+), 39 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 06d4ae89..589bf1c2 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "api/Api.h" #include "App.h" @@ -94,7 +95,6 @@ App::App(int argc, char **argv) : uv_signal_init(uv_default_loop(), &m_signal); } - App::~App() { delete m_network; @@ -148,7 +148,9 @@ int App::start() # ifndef XMRIG_NO_CC if (m_options->ccHost() && m_options->ccPort() > 0) { - m_ccclient = new CCClient(m_options); + uv_async_init(uv_default_loop(), &m_async, App::onCommandReceived); + + m_ccclient = new CCClient(m_options, &m_async); } else { LOG_WARN("Please configure CC-Url and restart. CC feature is now deactivated."); } @@ -219,7 +221,7 @@ void App::shutdown() m_self->stop(false); } -void App::onSignal(uv_signal_t *handle, int signum) +void App::onSignal(uv_signal_t* handle, int signum) { switch (signum) { @@ -242,3 +244,25 @@ void App::onSignal(uv_signal_t *handle, int signum) uv_signal_stop(handle); App::shutdown(); } + +void App::onCommandReceived(uv_async_t* async) +{ + if (async->data) { + auto command = reinterpret_cast (async->data); + switch (command) { + case ControlCommand::START: + Workers::setEnabled(true); + break; + case ControlCommand::STOP: + Workers::setEnabled(false); + break; + case ControlCommand::UPDATE_CONFIG:; + case ControlCommand::RESTART: + App::restart(); + break; + case ControlCommand::SHUTDOWN: + App::shutdown(); + break; + } + } +} \ No newline at end of file diff --git a/src/App.h b/src/App.h index 9451f191..215ae7d2 100644 --- a/src/App.h +++ b/src/App.h @@ -55,7 +55,8 @@ private: void background(); void stop(bool restart); - static void onSignal(uv_signal_t *handle, int signum); + static void onSignal(uv_signal_t* handle, int signum); + static void onCommandReceived(uv_async_t* handle); static App *m_self; @@ -67,6 +68,7 @@ private: Options *m_options; CCClient *m_ccclient; uv_signal_t m_signal; + uv_async_t m_async; }; diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp index 3cccfbb1..cf059eed 100644 --- a/src/cc/CCClient.cpp +++ b/src/cc/CCClient.cpp @@ -48,8 +48,9 @@ CCClient *CCClient::m_self = nullptr; uv_mutex_t CCClient::m_mutex; -CCClient::CCClient(const Options *options) - : m_options(options) +CCClient::CCClient(Options* options, uv_async_t* async) + : m_options(options), + m_async(async) { uv_mutex_init(&m_mutex); @@ -88,10 +89,7 @@ CCClient::CCClient(const Options *options) m_authorization = std::string("Bearer ") + m_self->m_options->ccToken(); } - uv_timer_init(uv_default_loop(), &m_timer); - uv_timer_start(&m_timer, CCClient::onReport, - static_cast(m_options->ccUpdateInterval() * 1000), - static_cast(m_options->ccUpdateInterval() * 1000)); + uv_thread_create(&m_thread, CCClient::onThreadStarted, this); } CCClient::~CCClient() @@ -102,32 +100,33 @@ CCClient::~CCClient() void CCClient::updateHashrate(const Hashrate *hashrate) { - uv_mutex_lock(&m_mutex); - if (m_self) { + uv_mutex_lock(&m_mutex); + m_self->m_clientStatus.setHashrateShort(hashrate->calc(Hashrate::ShortInterval)); m_self->m_clientStatus.setHashrateMedium(hashrate->calc(Hashrate::MediumInterval)); m_self->m_clientStatus.setHashrateLong(hashrate->calc(Hashrate::LargeInterval)); m_self->m_clientStatus.setHashrateHighest(hashrate->highest()); - } - uv_mutex_unlock(&m_mutex); + uv_mutex_unlock(&m_mutex); + } } void CCClient::updateNetworkState(const NetworkState &network) { - uv_mutex_lock(&m_mutex); - if (m_self) { + uv_mutex_lock(&m_mutex); + m_self->m_clientStatus.setCurrentStatus(Workers::isEnabled() ? ClientStatus::RUNNING : ClientStatus::PAUSED); m_self->m_clientStatus.setCurrentPool(network.pool); m_self->m_clientStatus.setSharesGood(network.accepted); m_self->m_clientStatus.setSharesTotal(network.accepted + network.rejected); m_self->m_clientStatus.setHashesTotal(network.total); m_self->m_clientStatus.setAvgTime(network.avgTime()); + + uv_mutex_unlock(&m_mutex); } - uv_mutex_unlock(&m_mutex); } void CCClient::publishClientStatusReport() @@ -148,23 +147,22 @@ void CCClient::publishClientStatusReport() if (controlCommand.getCommand() == ControlCommand::START) { if (!Workers::isEnabled()) { LOG_WARN("[CC-Client] Command: START received -> resume"); - Workers::setEnabled(true); } } else if (controlCommand.getCommand() == ControlCommand::STOP) { if (Workers::isEnabled()) { LOG_WARN("[CC-Client] Command: STOP received -> pause"); - Workers::setEnabled(false); } } else if (controlCommand.getCommand() == ControlCommand::UPDATE_CONFIG) { LOG_WARN("[CC-Client] Command: UPDATE_CONFIG received -> update config"); updateConfig(); } else if (controlCommand.getCommand() == ControlCommand::RESTART) { LOG_WARN("[CC-Client] Command: RESTART received -> restart"); - App::restart(); } else if (controlCommand.getCommand() == ControlCommand::SHUTDOWN) { LOG_WARN("[CC-Client] Command: SHUTDOWN received -> shutdown"); - App::shutdown(); } + + m_self->m_async->data = reinterpret_cast(controlCommand.getCommand()); + uv_async_send(m_self->m_async); } else { LOG_ERR("[CC-Client] Unknown command received from CC Server."); } @@ -196,8 +194,7 @@ void CCClient::updateConfig() clientConfigFile << buffer.GetString(); clientConfigFile.close(); - LOG_WARN("[CC-Client] Config updated. -> restart"); - App::restart(); + LOG_WARN("[CC-Client] Config updated. -> trigger restart"); } else { LOG_ERR("[CC-Client] Not able to store client config to file %s.", m_self->m_options->configFile()); } @@ -214,8 +211,8 @@ std::shared_ptr CCClient::performRequest(const std::string& r httplib::Client cli(m_self->m_options->ccHost(), m_self->m_options->ccPort()); httplib::Request req; - req.method = operation.c_str(); - req.path = requestUrl.c_str(); + req.method = operation; + req.path = requestUrl; req.set_header("Host", ""); req.set_header("Accept", "*/*"); req.set_header("User-Agent", Platform::userAgent()); @@ -227,7 +224,7 @@ std::shared_ptr CCClient::performRequest(const std::string& r } if (!requestBuffer.empty()) { - req.body = requestBuffer.c_str(); + req.body = requestBuffer; } auto res = std::make_shared(); @@ -235,6 +232,18 @@ std::shared_ptr CCClient::performRequest(const std::string& r return cli.send(req, *res) ? res : nullptr; } +void CCClient::onThreadStarted(void* handle) +{ + uv_loop_init(&m_self->m_client_loop); + + uv_timer_init(&m_self->m_client_loop, &m_self->m_timer); + uv_timer_start(&m_self->m_timer, CCClient::onReport, + static_cast(m_self->m_options->ccUpdateInterval() * 1000), + static_cast(m_self->m_options->ccUpdateInterval() * 1000)); + + uv_run(&m_self->m_client_loop, UV_RUN_DEFAULT); +} + void CCClient::onReport(uv_timer_t *handle) { if (m_self) { diff --git a/src/cc/CCClient.h b/src/cc/CCClient.h index 6a947ab9..09b04a70 100644 --- a/src/cc/CCClient.h +++ b/src/cc/CCClient.h @@ -38,7 +38,7 @@ class NetworkState; class CCClient { public: - CCClient(const Options *options); + CCClient(Options *options, uv_async_t* async); ~CCClient(); static void updateHashrate(const Hashrate *hashrate); @@ -52,9 +52,10 @@ private: const std::string& requestBuffer, const std::string& operation); + static void onThreadStarted(void *handle); static void onReport(uv_timer_t *handle); - const Options *m_options; + const Options* m_options; static CCClient* m_self; static uv_mutex_t m_mutex; @@ -63,7 +64,10 @@ private: std::string m_authorization; + uv_async_t* m_async; uv_timer_t m_timer; + uv_loop_t m_client_loop; + uv_thread_t m_thread; }; diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp index 3382e558..d8126c2e 100644 --- a/src/cc/ClientStatus.cpp +++ b/src/cc/ClientStatus.cpp @@ -32,12 +32,24 @@ #include "ClientStatus.h" ClientStatus::ClientStatus() - : m_hashrateShort(0), + : m_currentStatus(Status::PAUSED), + m_hasHugepages(false), + m_isHugepagesEnabled(false), + m_isDoubleHashMode(false), + m_isCpuX64(false), + m_hasCpuAES(false), + m_hashrateShort(0), m_hashrateMedium(0), m_hashrateLong(0), + m_hashrateHighest(0), + m_currentThreads(0), + m_cpuCores(0), + m_cpuL2(0), + m_cpuL3(0), m_sharesGood(0), m_sharesTotal(0), m_hashesTotal(0), + m_avgTime(0), m_lastStatusUpdate(0) { diff --git a/src/cc/ControlCommand.h b/src/cc/ControlCommand.h index 13b9b6e3..3fb10d4e 100644 --- a/src/cc/ControlCommand.h +++ b/src/cc/ControlCommand.h @@ -28,6 +28,14 @@ #include #include "rapidjson/document.h" +static const char* command_str[5] = { + "START", + "STOP", + "UPDATE_CONFIG", + "RESTART", + "SHUTDOWN" +}; + class ControlCommand { public: @@ -43,12 +51,12 @@ public: ControlCommand(); explicit ControlCommand(Command command); - inline const char *toString (Command command) + static inline const char *toString (Command command) { return command_str[static_cast(command)]; } - inline Command toCommand (const char *command) + static inline Command toCommand (const char *command) { const int n = sizeof(command_str) / sizeof(command_str[0]); for (int i = 0; i < n; ++i) @@ -69,14 +77,6 @@ public: bool isOneTimeCommand() const; private: - const char* command_str[5] = { - "START", - "STOP", - "UPDATE_CONFIG", - "RESTART", - "SHUTDOWN" - }; - Command m_command; };