diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d29bfbb4..d31160632 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+# v2.1.0
+- [#40](https://github.com/xmrig/xmrig/issues/40) Improved miner shutdown, fixed crash on exit for Linux and OS X.
+- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`.
+- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one.
+- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon.
+
+# v2.0.2
+- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates.
+- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0.
+
# v2.0.1
- [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ab51026f9..f6d189e8b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,8 +11,10 @@ include (CheckIncludeFile)
set(HEADERS
src/3rdparty/align.h
src/App.h
+ 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
@@ -58,6 +60,7 @@ set(HEADERS_CRYPTO
set(SOURCES
src/App.cpp
+ src/Console.cpp
src/log/ConsoleLog.cpp
src/log/FileLog.cpp
src/log/Log.cpp
@@ -65,10 +68,10 @@ set(SOURCES
src/net/Client.cpp
src/net/Job.cpp
src/net/Network.cpp
- src/net/Url.cpp
src/net/strategies/DonateStrategy.cpp
src/net/strategies/FailoverStrategy.cpp
src/net/strategies/SinglePoolStrategy.cpp
+ src/net/Url.cpp
src/Options.cpp
src/Summary.cpp
src/workers/DoubleWorker.cpp
@@ -94,8 +97,6 @@ set(SOURCES_CRYPTO
if (WIN32)
set(SOURCES_OS
res/app.rc
- src/3rdparty/winansi.cpp
- src/3rdparty/winansi.h
src/App_win.cpp
src/Cpu_win.cpp
src/Mem_win.cpp
diff --git a/README.md b/README.md
index d5d082835..7811f711c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# XMRig
XMRig is high performance Monero (XMR) CPU miner, with the official full Windows support.
-Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code.
+Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 complete rewritten from scratch on C++.
diff --git a/src/3rdparty/winansi.cpp b/src/3rdparty/winansi.cpp
deleted file mode 100644
index c6fbbc208..000000000
--- a/src/3rdparty/winansi.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/**
- * Old Git implementation of windows terminal colors (2009)
- * before use of a threaded wrapper.
- */
-
-#undef NOGDI
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "winansi.h"
-/*
-* Copyright 2008 Peter Harris
-*/
-
-/*
-Functions to be wrapped:
-*/
-#undef printf
-#undef fprintf
-#undef fputs
-#undef vfprintf
-/* TODO: write */
-
-/*
-ANSI codes used by git: m, K
-
-This file is git-specific. Therefore, this file does not attempt
-to implement any codes that are not used by git.
-*/
-
-static HANDLE console;
-static WORD plain_attr;
-static WORD attr;
-static int negative;
-
-static void init(void)
-{
- CONSOLE_SCREEN_BUFFER_INFO sbi;
-
- static int initialized = 0;
- if (initialized)
- return;
-
- console = GetStdHandle(STD_OUTPUT_HANDLE);
- if (console == INVALID_HANDLE_VALUE)
- console = NULL;
-
- if (!console)
- return;
-
- GetConsoleScreenBufferInfo(console, &sbi);
- attr = plain_attr = sbi.wAttributes;
- negative = 0;
-
- initialized = 1;
-}
-
-static int write_console(const char *str, int len)
-{
- /* convert utf-8 to utf-16, write directly to console */
- int wlen = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
- wchar_t *wbuf = (wchar_t *)alloca(wlen * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, str, len, wbuf, wlen);
-
- WriteConsoleW(console, wbuf, wlen, NULL, NULL);
-
- /* return original (utf-8 encoded) length */
- return len;
-}
-
-#define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
-#define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
-
-static void set_console_attr(void)
-{
- WORD attributes = attr;
- if (negative) {
- attributes &= ~FOREGROUND_ALL;
- attributes &= ~BACKGROUND_ALL;
-
- /* This could probably use a bitmask
- instead of a series of ifs */
- if (attr & FOREGROUND_RED)
- attributes |= BACKGROUND_RED;
- if (attr & FOREGROUND_GREEN)
- attributes |= BACKGROUND_GREEN;
- if (attr & FOREGROUND_BLUE)
- attributes |= BACKGROUND_BLUE;
-
- if (attr & BACKGROUND_RED)
- attributes |= FOREGROUND_RED;
- if (attr & BACKGROUND_GREEN)
- attributes |= FOREGROUND_GREEN;
- if (attr & BACKGROUND_BLUE)
- attributes |= FOREGROUND_BLUE;
- }
- SetConsoleTextAttribute(console, attributes);
-}
-
-static void erase_in_line(void)
-{
- CONSOLE_SCREEN_BUFFER_INFO sbi;
- DWORD dummy; /* Needed for Windows 7 (or Vista) regression */
-
- if (!console)
- return;
-
- GetConsoleScreenBufferInfo(console, &sbi);
- FillConsoleOutputCharacterA(console, ' ',
- sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
- &dummy);
-}
-
-
-static const char *set_attr(const char *str)
-{
- const char *func;
- size_t len = strspn(str, "0123456789;");
- func = str + len;
-
- switch (*func) {
- case 'm':
- do {
- long val = strtol(str, (char **)&str, 10);
- switch (val) {
- case 0: /* reset */
- attr = plain_attr;
- negative = 0;
- break;
- case 1: /* bold */
- attr |= FOREGROUND_INTENSITY;
- break;
- case 2: /* faint */
- case 22: /* normal */
- attr &= ~FOREGROUND_INTENSITY;
- break;
- case 3: /* italic */
- /* Unsupported */
- break;
- case 4: /* underline */
- case 21: /* double underline */
- /* Wikipedia says this flag does nothing */
- /* Furthermore, mingw doesn't define this flag
- attr |= COMMON_LVB_UNDERSCORE; */
- break;
- case 24: /* no underline */
- /* attr &= ~COMMON_LVB_UNDERSCORE; */
- break;
- case 5: /* slow blink */
- case 6: /* fast blink */
- /* We don't have blink, but we do have
- background intensity */
- attr |= BACKGROUND_INTENSITY;
- break;
- case 25: /* no blink */
- attr &= ~BACKGROUND_INTENSITY;
- break;
- case 7: /* negative */
- negative = 1;
- break;
- case 27: /* positive */
- negative = 0;
- break;
- case 8: /* conceal */
- case 28: /* reveal */
- /* Unsupported */
- break;
- case 30: /* Black */
- attr &= ~FOREGROUND_ALL;
- break;
- case 31: /* Red */
- attr &= ~FOREGROUND_ALL;
- attr |= FOREGROUND_RED;
- break;
- case 32: /* Green */
- attr &= ~FOREGROUND_ALL;
- attr |= FOREGROUND_GREEN;
- break;
- case 33: /* Yellow */
- attr &= ~FOREGROUND_ALL;
- attr |= FOREGROUND_RED | FOREGROUND_GREEN;
- break;
- case 34: /* Blue */
- attr &= ~FOREGROUND_ALL;
- attr |= FOREGROUND_BLUE;
- break;
- case 35: /* Magenta */
- attr &= ~FOREGROUND_ALL;
- attr |= FOREGROUND_RED | FOREGROUND_BLUE;
- break;
- case 36: /* Cyan */
- attr &= ~FOREGROUND_ALL;
- attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;
- break;
- case 37: /* White */
- attr |= FOREGROUND_RED |
- FOREGROUND_GREEN |
- FOREGROUND_BLUE;
- break;
- case 38: /* Unknown */
- break;
- case 39: /* reset */
- attr &= ~FOREGROUND_ALL;
- attr |= (plain_attr & FOREGROUND_ALL);
- break;
- case 40: /* Black */
- attr &= ~BACKGROUND_ALL;
- break;
- case 41: /* Red */
- attr &= ~BACKGROUND_ALL;
- attr |= BACKGROUND_RED;
- break;
- case 42: /* Green */
- attr &= ~BACKGROUND_ALL;
- attr |= BACKGROUND_GREEN;
- break;
- case 43: /* Yellow */
- attr &= ~BACKGROUND_ALL;
- attr |= BACKGROUND_RED | BACKGROUND_GREEN;
- break;
- case 44: /* Blue */
- attr &= ~BACKGROUND_ALL;
- attr |= BACKGROUND_BLUE;
- break;
- case 45: /* Magenta */
- attr &= ~BACKGROUND_ALL;
- attr |= BACKGROUND_RED | BACKGROUND_BLUE;
- break;
- case 46: /* Cyan */
- attr &= ~BACKGROUND_ALL;
- attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;
- break;
- case 47: /* White */
- attr |= BACKGROUND_RED |
- BACKGROUND_GREEN |
- BACKGROUND_BLUE;
- break;
- case 48: /* Unknown */
- break;
- case 49: /* reset */
- attr &= ~BACKGROUND_ALL;
- attr |= (plain_attr & BACKGROUND_ALL);
- break;
- default:
- /* Unsupported code */
- break;
- }
- str++;
- } while (*(str - 1) == ';');
-
- set_console_attr();
- break;
- case 'K':
- erase_in_line();
- break;
- default:
- /* Unsupported code */
- break;
- }
-
- return func + 1;
-}
-
-static int ansi_emulate(const char *str, FILE *stream)
-{
- int rv = 0;
- const char *pos = str;
-
- fflush(stream);
-
- while (*pos) {
- pos = strstr(str, "\033[");
- if (pos) {
- int len = (int) (pos - str);
-
- if (len) {
- int out_len = write_console(str, len);
- rv += out_len;
- if (out_len < len)
- return rv;
- }
-
- str = pos + 2;
- rv += 2;
-
- pos = set_attr(str);
- rv += (int) (pos - str);
- str = pos;
- }
- else {
- int len = (int) strlen(str);
- rv += write_console(str, len);
- return rv;
- }
- }
- return rv;
-}
-
-int winansi_fputs(const char *str, FILE *stream)
-{
- int rv;
-
- if (!isatty(fileno(stream)))
- return fputs(str, stream);
-
- init();
-
- if (!console)
- return fputs(str, stream);
-
- rv = ansi_emulate(str, stream);
-
- if (rv >= 0)
- return 0;
- else
- return EOF;
-}
-
-int winansi_vfprintf(FILE *stream, const char *format, va_list list)
-{
- int len, rv;
- char small_buf[256] = { 0 };
- char *buf = small_buf;
- va_list cp;
-
- if (!isatty(fileno(stream)))
- goto abort;
-
- init();
-
- if (!console)
- goto abort;
-
- va_copy(cp, list);
- len = vsnprintf(small_buf, sizeof(small_buf), format, cp);
-#ifdef WIN32
- /* bug on long strings without that */
- if (len == -1)
- len = _vscprintf(format, cp);
-#endif
- va_end(cp);
-
- if ((unsigned) len > sizeof(small_buf) - 1) {
- buf = (char*)malloc(len + 1);
- if (!buf)
- goto abort;
-
- len = vsnprintf(buf, len + 1, format, list);
-#ifdef WIN32
- if (len == -1)
- len = _vscprintf(format, list);
-#endif
- }
-
- rv = ansi_emulate(buf, stream);
-
- if (buf != small_buf)
- free(buf);
- return rv;
-
-abort:
- rv = vfprintf(stream, format, list);
- return rv;
-}
-
-int winansi_fprintf(FILE *stream, const char *format, ...)
-{
- va_list list;
- int rv;
-
- va_start(list, format);
- rv = winansi_vfprintf(stream, format, list);
- va_end(list);
-
- return rv;
-}
-
-int winansi_printf(const char *format, ...)
-{
- va_list list;
- int rv;
-
- va_start(list, format);
- rv = winansi_vfprintf(stdout, format, list);
- va_end(list);
-
- return rv;
-}
diff --git a/src/3rdparty/winansi.h b/src/3rdparty/winansi.h
deleted file mode 100644
index 47914c364..000000000
--- a/src/3rdparty/winansi.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * ANSI emulation wrappers
- */
-
-#include
-#include
-#include
-
-#define fileno(fd) _fileno(fd)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- int winansi_fputs(const char *str, FILE *stream);
- int winansi_printf(const char *format, ...);
- int winansi_fprintf(FILE *stream, const char *format, ...);
- int winansi_vfprintf(FILE *stream, const char *format, va_list list);
-#ifdef __cplusplus
-}
-#endif
-
-#undef fputs
-#undef fprintf
-#undef vfprintf
-
-#define fputs winansi_fputs
-#define printf winansi_printf
-#define fprintf winansi_fprintf
-#define vfprintf winansi_vfprintf
diff --git a/src/App.cpp b/src/App.cpp
index aff9ee954..4ef8a1a64 100644
--- a/src/App.cpp
+++ b/src/App.cpp
@@ -27,6 +27,7 @@
#include "App.h"
+#include "Console.h"
#include "Cpu.h"
#include "crypto/CryptoNight.h"
#include "log/ConsoleLog.h"
@@ -50,6 +51,7 @@ App *App::m_self = nullptr;
App::App(int argc, char **argv) :
+ m_console(nullptr),
m_network(nullptr),
m_options(nullptr)
{
@@ -62,6 +64,7 @@ App::App(int argc, char **argv) :
if (!m_options->background()) {
Log::add(new ConsoleLog(m_options->colors()));
+ m_console = new Console(this);
}
if (m_options->logFile()) {
@@ -82,6 +85,7 @@ App::App(int argc, char **argv) :
App::~App()
{
+ delete m_console;
}
@@ -121,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 99eac4329..77bf973b8 100644
--- a/src/App.h
+++ b/src/App.h
@@ -28,11 +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);
@@ -40,6 +44,9 @@ public:
int exec();
+protected:
+ void onConsoleCommand(char command) override;
+
private:
void background();
void close();
@@ -48,6 +55,7 @@ private:
static App *m_self;
+ Console *m_console;
Network *m_network;
Options *m_options;
uv_signal_t m_signal;
diff --git a/src/Console.cpp b/src/Console.cpp
new file mode 100644
index 000000000..15c990018
--- /dev/null
+++ b/src/Console.cpp
@@ -0,0 +1,57 @@
+/* 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 .
+ */
+
+
+#include "Console.h"
+#include "interfaces/IConsoleListener.h"
+
+
+Console::Console(IConsoleListener *listener)
+ : m_listener(listener)
+{
+ m_tty.data = this;
+ uv_tty_init(uv_default_loop(), &m_tty, 0, 1);
+ uv_tty_set_mode(&m_tty, UV_TTY_MODE_RAW);
+
+ uv_read_start(reinterpret_cast(&m_tty), Console::onAllocBuffer, Console::onRead);
+}
+
+
+void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
+{
+ auto console = static_cast(handle->data);
+ buf->len = 1;
+ buf->base = console->m_buf;
+}
+
+
+void Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
+{
+ if (nread < 0) {
+ return uv_close(reinterpret_cast(stream), nullptr);
+ }
+
+ if (nread == 1) {
+ static_cast(stream->data)->m_listener->onConsoleCommand(buf->base[0]);
+ }
+}
diff --git a/src/Console.h b/src/Console.h
new file mode 100644
index 000000000..bde95d7d5
--- /dev/null
+++ b/src/Console.h
@@ -0,0 +1,49 @@
+/* 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 __CONSOLE_H__
+#define __CONSOLE_H__
+
+
+#include
+
+
+class IConsoleListener;
+
+
+class Console
+{
+public:
+ 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;
+};
+
+
+#endif /* __CONSOLE_H__ */
diff --git a/src/Summary.cpp b/src/Summary.cpp
index 959ccfad7..b7376b8e7 100644
--- a/src/Summary.cpp
+++ b/src/Summary.cpp
@@ -50,11 +50,8 @@ static void print_versions()
# endif
- if (Options::i()->colors()) {
- Log::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf);
- } else {
- Log::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf);
- }
+ Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s",
+ APP_VERSION, uv_version_string(), buf);
}
@@ -130,6 +127,17 @@ static void print_pools()
}
+static void print_commands()
+{
+ if (Options::i()->colors()) {
+ Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume");
+ }
+ else {
+ Log::i()->text(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume");
+ }
+}
+
+
void Summary::print()
{
print_versions();
@@ -137,6 +145,7 @@ void Summary::print()
print_cpu();
print_threads();
print_pools();
+ print_commands();
}
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/log/ConsoleLog.cpp b/src/log/ConsoleLog.cpp
index d9e86318d..51e8040a1 100644
--- a/src/log/ConsoleLog.cpp
+++ b/src/log/ConsoleLog.cpp
@@ -27,13 +27,12 @@
#include
#include
-
#ifdef WIN32
# include
-# include
-# include "3rdparty/winansi.h"
+# include
#endif
+
#include "log/ConsoleLog.h"
#include "log/Log.h"
@@ -41,6 +40,19 @@
ConsoleLog::ConsoleLog(bool colors) :
m_colors(colors)
{
+ uv_tty_init(uv_default_loop(), &m_tty, 1, 0);
+ uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
+
+# ifdef WIN32
+ HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
+ if (handle != INVALID_HANDLE_VALUE) {
+ DWORD mode = 0;
+ if (GetConsoleMode(handle, &mode)) {
+ mode &= ~ENABLE_QUICK_EDIT_MODE;
+ SetConsoleMode(handle, mode | ENABLE_EXTENDED_FLAGS);
+ }
+ }
+# endif
}
@@ -81,7 +93,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
}
const size_t len = 64 + strlen(fmt) + 2;
- char *buf = static_cast(alloca(len));
+ char *buf = new char[len];
sprintf(buf, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n",
stime.tm_year + 1900,
@@ -95,18 +107,35 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
m_colors ? Log::kCL_N : ""
);
- vfprintf(stdout, buf, args);
- fflush(stdout);
+ print(buf, args);
}
void ConsoleLog::text(const char* fmt, va_list args)
{
const int len = 64 + strlen(fmt) + 2;
- char *buf = static_cast(alloca(len));
+ char *buf = new char[len];
sprintf(buf, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
- vfprintf(stdout, buf, args);
- fflush(stdout);
+ print(buf, args);
+}
+
+
+void ConsoleLog::print(char *fmt, va_list args)
+{
+ vsnprintf(m_buf, sizeof(m_buf) - 1, fmt, args);
+ delete [] fmt;
+
+ uv_buf_t buf;
+ buf.base = strdup(m_buf);
+ buf.len = strlen(buf.base);
+
+ uv_write_t *req = new uv_write_t;
+ req->data = buf.base;
+
+ uv_write(req, reinterpret_cast(&m_tty), &buf, 1, [](uv_write_t *req, int status) {
+ free(req->data);
+ delete req;
+ });
}
diff --git a/src/log/ConsoleLog.h b/src/log/ConsoleLog.h
index 9b6777a59..b96b5e50c 100644
--- a/src/log/ConsoleLog.h
+++ b/src/log/ConsoleLog.h
@@ -25,6 +25,9 @@
#define __CONSOLELOG_H__
+#include
+
+
#include "interfaces/ILogBackend.h"
@@ -33,11 +36,15 @@ class ConsoleLog : public ILogBackend
public:
ConsoleLog(bool colors);
- void message(int level, const char* fmt, va_list args) override;
- void text(const char* fmt, va_list args) override;
+ void message(int level, const char *fmt, va_list args) override;
+ void text(const char *fmt, va_list args) override;
private:
+ void print(char *fmt, va_list args);
+
bool m_colors;
+ char m_buf[512];
+ uv_tty_t m_tty;
};
#endif /* __CONSOLELOG_H__ */
diff --git a/src/log/FileLog.cpp b/src/log/FileLog.cpp
index a1e801593..224c600dc 100644
--- a/src/log/FileLog.cpp
+++ b/src/log/FileLog.cpp
@@ -28,13 +28,6 @@
#include
-#ifdef WIN32
-# include
-# include
-# include "3rdparty/winansi.h"
-#endif
-
-
#include "log/FileLog.h"
diff --git a/src/log/Log.cpp b/src/log/Log.cpp
index 541486ebd..1efd486a4 100644
--- a/src/log/Log.cpp
+++ b/src/log/Log.cpp
@@ -28,12 +28,6 @@
#include
-#ifdef WIN32
-# include
-# include
-# include "3rdparty/winansi.h"
-#endif
-
#include "interfaces/ILogBackend.h"
#include "log/Log.h"
diff --git a/src/net/Client.cpp b/src/net/Client.cpp
index 62dcdb3d5..001415c8b 100644
--- a/src/net/Client.cpp
+++ b/src/net/Client.cpp
@@ -100,12 +100,12 @@ int64_t Client::send(char *data, size_t size)
uv_buf_t buf = uv_buf_init(data, size ? size : strlen(data));
- uv_write_t *req = static_cast(malloc(sizeof(uv_write_t)));
+ uv_write_t *req = new uv_write_t;
req->data = buf.base;
uv_write(req, m_stream, &buf, 1, [](uv_write_t *req, int status) {
free(req->data);
- free(req);
+ delete req;
});
uv_timer_start(&m_responseTimer, [](uv_timer_t *handle) { getClient(handle->data)->close(); }, kResponseTimeout, 0);
@@ -202,6 +202,11 @@ bool Client::parseJob(const json_t *params, int *code)
return false;
}
+ if (m_job == job) {
+ LOG_WARN("[%s:%u] duplicate job received, ignore", m_url.host(), m_url.port());
+ return false;
+ }
+
m_job = std::move(job);
return true;
}
diff --git a/src/version.h b/src/version.h
index c23fbe9d0..6875f7f98 100644
--- a/src/version.h
+++ b/src/version.h
@@ -27,7 +27,7 @@
#define APP_ID "xmrig"
#define APP_NAME "XMRig"
#define APP_DESC "Monero (XMR) CPU miner"
-#define APP_VERSION "2.1.0-dev"
+#define APP_VERSION "2.1.0"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"
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);