This commit is contained in:
SChernykh 2021-08-24 13:46:53 +02:00
commit a55545762b
4 changed files with 111 additions and 37 deletions

View file

@ -1,6 +1,7 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2021 hyc <https://github.com/hyc>
*
* 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
@ -51,6 +52,89 @@ ConsoleCommands::~ConsoleCommands()
LOGINFO(1, "stopped");
}
typedef struct strconst {
const char *str;
size_t len;
} strconst;
#define STRCONST(x) {x, sizeof(x)-1}
#define STRCNULL {NULL, 0}
typedef int (cmdfunc)(p2pool *pool, const char *args);
typedef struct cmd {
strconst name;
const char *arg;
const char *descr;
cmdfunc *func;
} cmd;
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_exit;
static cmd cmds[] = {
{ STRCONST("help"), "", "display list of commands", do_help },
{ STRCONST("status"), "", "display p2pool status", do_status },
{ STRCONST("loglevel"), "<level>", "set log level", do_loglevel },
{ STRCONST("addpeers"), "<peeraddr>", "add peer", do_addpeers },
{ STRCONST("droppeers"), "", "disconnect all peers", do_droppeers },
{ STRCONST("exit"), "", "terminate p2pool", do_exit },
{ STRCNULL, NULL, NULL, NULL }
};
static int do_help(p2pool * /* m_pool */, const char * /* args */)
{
int i;
LOGINFO(0, "List of commands");
for (i=0; cmds[i].name.len; i++)
LOGINFO(0, cmds[i].name.str << " " << cmds[i].arg << "\t" << cmds[i].descr);
return 0;
}
static int do_status(p2pool *m_pool, const char * /* args */)
{
m_pool->side_chain().print_status();
if (m_pool->stratum_server()) {
m_pool->stratum_server()->print_status();
}
if (m_pool->p2p_server()) {
m_pool->p2p_server()->print_status();
}
return 0;
}
static int do_loglevel(p2pool * /* m_pool */, const char *args)
{
int level = atoi(args);
level = std::min(std::max(level, 0), 5);
log::GLOBAL_LOG_LEVEL = level;
LOGINFO(0, "log level set to " << level);
return 0;
}
static int do_addpeers(p2pool *m_pool, const char *args)
{
if (m_pool->p2p_server()) {
m_pool->p2p_server()->connect_to_peers(args);
}
return 0;
}
static int do_droppeers(p2pool *m_pool, const char * /* args */)
{
if (m_pool->p2p_server()) {
m_pool->p2p_server()->drop_connections();
}
return 0;
}
static int do_exit(p2pool *m_pool, const char * /* args */)
{
m_pool->stop();
return 1;
}
void ConsoleCommands::run()
{
LOGINFO(1, "started");
@ -58,51 +142,24 @@ void ConsoleCommands::run()
std::string command;
command.reserve(1024);
constexpr char status[] = "status";
constexpr char loglevel[] = "loglevel";
constexpr char addpeers[] = "addpeers";
constexpr char droppeers[] = "droppeers";
do {
std::getline(std::cin, command);
if (stopped || std::cin.eof()) {
return;
}
if (command.find(status) == 0) {
m_pool->side_chain().print_status();
if (m_pool->stratum_server()) {
m_pool->stratum_server()->print_status();
int i;
for (i=0; cmds[i].name.len; i++) {
if (!strncmp(command.c_str(), cmds[i].name.str, cmds[i].name.len)) {
const char *args = command.c_str() + cmds[i].name.len + 1;
int rc = cmds[i].func(m_pool, args);
if ( rc )
return;
break;
}
if (m_pool->p2p_server()) {
m_pool->p2p_server()->print_status();
}
continue;
}
if (command.find(loglevel) == 0) {
int level = atoi(command.c_str() + sizeof(loglevel));
level = std::min(std::max(level, 0), 5);
log::GLOBAL_LOG_LEVEL = level;
LOGINFO(0, "log level set to " << level);
continue;
}
if (command.find(addpeers) == 0) {
if (m_pool->p2p_server()) {
m_pool->p2p_server()->connect_to_peers(command.c_str() + sizeof(addpeers));
}
continue;
}
if (command.find(droppeers) == 0) {
if (m_pool->p2p_server()) {
m_pool->p2p_server()->drop_connections();
}
continue;
}
LOGWARN(0, "Unknown command " << command);
if (!cmds[i].name.len)
LOGWARN(0, "Unknown command " << command);
} while (true);
}

View file

@ -659,6 +659,17 @@ static bool init_signals()
return true;
}
void p2pool::stop()
{
uv_async_t asy;
uv_loop_t *loop = uv_default_loop();
/* use async handle to make sure event loops wake up and stop */
uv_async_init(loop, &asy, NULL);
uv_stop(loop);
uv_async_send(&asy);
}
int p2pool::run()
{
if (!m_params->ok()) {

View file

@ -41,6 +41,7 @@ public:
int run();
bool stopped() const { return m_stopped; }
void stop();
const Params& params() const { return *m_params; }
BlockTemplate& block_template() { return *m_blockTemplate; }

View file

@ -393,6 +393,11 @@ void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::shutdown_tcp()
uv_close(reinterpret_cast<uv_handle_t*>(s), [](uv_handle_t* h) { delete reinterpret_cast<uv_tcp_t*>(h); });
}
uv_async_t asy;
uv_async_init(&m_loop, &asy, NULL);
uv_stop(&m_loop);
uv_async_send(&asy);
uv_thread_join(&m_loopThread);
uv_loop_close(&m_loop);