diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp index 8ed1769b1..8aaf75f3a 100644 --- a/tools/dhtnode.cpp +++ b/tools/dhtnode.cpp @@ -386,8 +386,7 @@ main(int argc, char **argv) } if (params.daemonize or params.service) { - while (true) - std::this_thread::sleep_for(std::chrono::seconds(30)); + while (runner.wait()); } else { cmd_loop(dht, params); } diff --git a/tools/tools_common.h b/tools/tools_common.h index d8cc540bf..933cc7e2a 100644 --- a/tools/tools_common.h +++ b/tools/tools_common.h @@ -18,6 +18,7 @@ */ // Common utility methods used by C++ OpenDHT tools. +#pragma once #include #ifndef WIN32_NATIVE @@ -37,6 +38,8 @@ #include #include #include +#include +#include #include #include #include @@ -204,13 +207,33 @@ readLine(const char* prefix = PROMPT) return line_read ? std::string(line_read) : std::string("\0", 1); } +struct ServiceRunner { + bool wait() { + std::unique_lock lock(m); + cv.wait(lock, [&]{return terminate;}); + return !terminate; + } + void kill() { + std::lock_guard lock(m); + terminate = true; + cv.notify_all(); + } +private: + std::condition_variable cv; + std::mutex m; + bool terminate = false; +}; + +ServiceRunner runner; + void signal_handler(int sig) { switch(sig) { case SIGHUP: break; + case SIGINT: case SIGTERM: - exit(EXIT_SUCCESS); + runner.kill(); break; } } @@ -223,6 +246,7 @@ void setupSignals() signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGHUP,signal_handler); /* catch hangup signal */ + signal(SIGINT,signal_handler); /* catch interrupt signal */ signal(SIGTERM,signal_handler); /* catch kill signal */ #endif }