aboutsummaryrefslogtreecommitdiff
path: root/src/common/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/util.h')
-rw-r--r--src/common/util.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/common/util.h b/src/common/util.h
index a29a30fff..af92adf94 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -4,6 +4,7 @@
#pragma once
+#include <mutex>
#include <system_error>
#include <boost/filesystem.hpp>
@@ -26,4 +27,60 @@ namespace tools
s.append(reinterpret_cast<const char*>(&pot.time), sizeof(pot.time));
return crypto::cn_fast_hash(s.data(), s.size());
}
+
+
+ class signal_handler
+ {
+ public:
+ template<typename T>
+ static bool install(T t)
+ {
+#if defined(WIN32)
+ bool r = TRUE == ::SetConsoleCtrlHandler(&win_handler, TRUE);
+ if (r)
+ {
+ m_handler = t;
+ }
+ return r;
+#else
+ signal(SIGINT, posix_handler);
+ signal(SIGTERM, posix_handler);
+ m_handler = t;
+ return true;
+#endif
+ }
+
+ private:
+#if defined(WIN32)
+ static BOOL win_handler(DWORD type)
+ {
+ if (CTRL_C_EVENT == type || CTRL_BREAK_EVENT == type)
+ {
+ handle_signal();
+ return TRUE;
+ }
+ else
+ {
+ LOG_PRINT_RED_L0("Got control signal " << type << ". Exiting without saving...");
+ return FALSE;
+ }
+ return TRUE;
+ }
+#else
+ static void posix_handler(int /*type*/)
+ {
+ handle_signal();
+ }
+#endif
+
+ static void handle_signal()
+ {
+ static std::mutex m_mutex;
+ std::unique_lock<std::mutex> lock(m_mutex);
+ m_handler();
+ }
+
+ private:
+ static std::function<void(void)> m_handler;
+ };
}