diff --git a/CMakeLists.txt b/CMakeLists.txt index b91b99d62..f6d189e8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(HEADERS src/Console.h src/Cpu.h src/interfaces/IClientListener.h + src/interfaces/IConsoleListener.h src/interfaces/IJobResultListener.h src/interfaces/ILogBackend.h src/interfaces/IStrategy.h diff --git a/src/App.cpp b/src/App.cpp index b7b66556c..4ef8a1a64 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -64,7 +64,7 @@ App::App(int argc, char **argv) : if (!m_options->background()) { Log::add(new ConsoleLog(m_options->colors())); - m_console = new Console(); + m_console = new Console(this); } if (m_options->logFile()) { @@ -125,6 +125,39 @@ int App::exec() } +void App::onConsoleCommand(char command) +{ + switch (command) { + case 'h': + case 'H': + Workers::printHashrate(true); + break; + + case 'p': + case 'P': + LOG_INFO(m_options->colors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume"); + Workers::setEnabled(false); + break; + + case 'r': + case 'R': + if (!Workers::isEnabled()) { + LOG_INFO(m_options->colors() ? "\x1B[01;32mresumed" : "resumed"); + Workers::setEnabled(true); + } + break; + + case 3: + LOG_WARN("Ctrl+C received, exiting"); + close(); + break; + + default: + break; + } +} + + void App::close() { m_network->stop(); diff --git a/src/App.h b/src/App.h index 106a3267a..77bf973b8 100644 --- a/src/App.h +++ b/src/App.h @@ -28,12 +28,15 @@ #include +#include "interfaces/IConsoleListener.h" + + class Console; class Network; class Options; -class App +class App : public IConsoleListener { public: App(int argc, char **argv); @@ -41,6 +44,9 @@ public: int exec(); +protected: + void onConsoleCommand(char command) override; + private: void background(); void close(); diff --git a/src/Console.cpp b/src/Console.cpp index 7772aec07..15c990018 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -23,9 +23,11 @@ #include "Console.h" +#include "interfaces/IConsoleListener.h" -Console::Console() +Console::Console(IConsoleListener *listener) + : m_listener(listener) { m_tty.data = this; uv_tty_init(uv_default_loop(), &m_tty, 0, 1); @@ -50,6 +52,6 @@ void Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) } if (nread == 1) { - printf("%c\n", buf->base[0]); + static_cast(stream->data)->m_listener->onConsoleCommand(buf->base[0]); } } diff --git a/src/Console.h b/src/Console.h index 3726a066d..bde95d7d5 100644 --- a/src/Console.h +++ b/src/Console.h @@ -28,16 +28,20 @@ #include +class IConsoleListener; + + class Console { public: - Console(); + Console(IConsoleListener *listener); private: static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); char m_buf[1]; + IConsoleListener *m_listener; uv_tty_t m_tty; }; diff --git a/src/interfaces/IConsoleListener.h b/src/interfaces/IConsoleListener.h new file mode 100644 index 000000000..723f87dff --- /dev/null +++ b/src/interfaces/IConsoleListener.h @@ -0,0 +1,37 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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. + * + * 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 this program. If not, see . + */ + +#ifndef __ICONSOLELISTENER_H__ +#define __ICONSOLELISTENER_H__ + + +class IConsoleListener +{ +public: + virtual ~IConsoleListener() {} + + virtual void onConsoleCommand(char command) = 0; +}; + + +#endif // __ICONSOLELISTENER_H__ diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 243ba1b92..794fa289e 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -69,6 +69,10 @@ void DoubleWorker::start() } while (Workers::isPaused()); + if (Workers::sequence() == 0) { + break; + } + consumeJob(); } diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 58c69e7f4..34045f749 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -45,6 +45,10 @@ void SingleWorker::start() } while (Workers::isPaused()); + if (Workers::sequence() == 0) { + break; + } + consumeJob(); } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index e6717bbc8..b056c826c 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -60,6 +60,12 @@ Job Workers::job() } +void Workers::printHashrate(bool detail) +{ + m_hashrate->print(); +} + + void Workers::setEnabled(bool enabled) { if (m_enabled == enabled) { @@ -121,6 +127,7 @@ void Workers::stop() m_hashrate->stop(); uv_close(reinterpret_cast(&m_async), nullptr); + m_paused = 0; m_sequence = 0; for (size_t i = 0; i < m_workers.size(); ++i) { diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 850a909e7..0caf22a20 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -43,6 +43,7 @@ class Workers { public: static Job job(); + static void printHashrate(bool detail); static void setEnabled(bool enabled); static void setJob(const Job &job); static void start(int64_t affinity);