From c385355c38be43497aa9d5fecbf2bf209b0ca340 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 16 Jul 2019 11:28:20 +0200 Subject: [PATCH] DaemonCommand: make the atomics a bit more atomic Just to be sure. refs #5230 --- lib/base/CMakeLists.txt | 1 + lib/base/atomic.hpp | 43 +++++++++++++++++++++++++++++++++++++++ lib/cli/daemoncommand.cpp | 16 +++++++-------- 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 lib/base/atomic.hpp diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index fb3de3029..100ca27a7 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -15,6 +15,7 @@ set(base_SOURCES i2-base.hpp application.cpp application.hpp application-ti.hpp application-version.cpp application-environment.cpp array.cpp array.hpp array-script.cpp + atomic.hpp base64.cpp base64.hpp boolean.cpp boolean.hpp boolean-script.cpp configobject.cpp configobject.hpp configobject-ti.hpp configobject-script.cpp diff --git a/lib/base/atomic.hpp b/lib/base/atomic.hpp new file mode 100644 index 000000000..0ebcddefb --- /dev/null +++ b/lib/base/atomic.hpp @@ -0,0 +1,43 @@ +/* Icinga 2 | (c) 2019 Icinga GmbH | GPLv2+ */ + +#ifndef ATOMIC_H +#define ATOMIC_H + +#include + +namespace icinga +{ + +/** + * Extends std::atomic with an atomic constructor. + * + * @ingroup base + */ +template +class Atomic : public std::atomic { +public: + /** + * Like std::atomic#atomic, but operates atomically + * + * @param desired Initial value + */ + inline Atomic(T desired) + { + this->store(desired); + } + + /** + * Like std::atomic#atomic, but operates atomically + * + * @param desired Initial value + * @param order Initial store operation's memory order + */ + inline Atomic(T desired, std::memory_order order) + { + this->store(desired, order); + } +}; + +} + +#endif /* ATOMIC_H */ diff --git a/lib/cli/daemoncommand.cpp b/lib/cli/daemoncommand.cpp index 33a6343f1..cdc105dc6 100644 --- a/lib/cli/daemoncommand.cpp +++ b/lib/cli/daemoncommand.cpp @@ -7,6 +7,7 @@ #include "config/configcompiler.hpp" #include "config/configcompilercontext.hpp" #include "config/configitembuilder.hpp" +#include "base/atomic.hpp" #include "base/defer.hpp" #include "base/logger.hpp" #include "base/application.hpp" @@ -17,7 +18,6 @@ #include "base/scriptglobal.hpp" #include "base/context.hpp" #include "config.h" -#include #include #include #include @@ -186,7 +186,7 @@ std::vector DaemonCommand::GetArgumentSuggestions(const String& argument pid_t l_UmbrellaPid = 0; // Whether the umbrella process allowed us to continue working beyond config validation -static std::atomic l_AllowedToWork (false); +static Atomic l_AllowedToWork (false); #endif /* _WIN32 */ /** @@ -284,19 +284,19 @@ static const sigset_t l_UnixWorkerSignals = ([]() -> sigset_t { })(); // The PID of the seemless worker currently being started by StartUnixWorker() -static std::atomic l_CurrentlyStartingUnixWorkerPid (-1); +static Atomic l_CurrentlyStartingUnixWorkerPid (-1); // The state of the seemless worker currently being started by StartUnixWorker() -static std::atomic l_CurrentlyStartingUnixWorkerState (UnixWorkerState::Pending); +static Atomic l_CurrentlyStartingUnixWorkerState (UnixWorkerState::Pending); // The last temination signal we received -static std::atomic l_TermSignal (-1); +static Atomic l_TermSignal (-1); // Whether someone requested to re-load config (and we didn't handle that request, yet) -static std::atomic l_RequestedReload (false); +static Atomic l_RequestedReload (false); // Whether someone requested to re-open logs (and we didn't handle that request, yet) -static std::atomic l_RequestedReopenLogs (false); +static Atomic l_RequestedReopenLogs (false); /** * Umbrella process' signal handlers @@ -374,7 +374,7 @@ static void WorkerSignalHandler(int num, siginfo_t *info, void*) #ifdef HAVE_SYSTEMD // When we last notified the watchdog. -static std::atomic l_LastNotifiedWatchdog (0); +static Atomic l_LastNotifiedWatchdog (0); /** * Notify the watchdog if not notified during the last 2.5s.