From 56ae875861ab260b80a030f50c4aff9f9dc8fff0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:32:39 +0200 Subject: Adding upstream version 2.14.2. Signed-off-by: Daniel Baumann --- lib/base/atomic.hpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 lib/base/atomic.hpp (limited to 'lib/base/atomic.hpp') diff --git a/lib/base/atomic.hpp b/lib/base/atomic.hpp new file mode 100644 index 0000000..c8f169c --- /dev/null +++ b/lib/base/atomic.hpp @@ -0,0 +1,91 @@ +/* Icinga 2 | (c) 2019 Icinga GmbH | GPLv2+ */ + +#ifndef ATOMIC_H +#define ATOMIC_H + +#include +#include +#include +#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); + } +}; + +/** + * Wraps any T into a std::atomic-like interface that locks using a mutex. + * + * In contrast to std::atomic, Locked is also valid for types that are not trivially copyable. + * In case T is trivially copyable, std::atomic is almost certainly the better choice. + * + * @ingroup base + */ +template +class Locked +{ +public: + inline T load() const + { + std::unique_lock lock(m_Mutex); + + return m_Value; + } + + inline void store(T desired) + { + std::unique_lock lock(m_Mutex); + + m_Value = std::move(desired); + } + +private: + mutable std::mutex m_Mutex; + T m_Value; +}; + +/** + * Type alias for std::atomic if possible, otherwise Locked is used as a fallback. + * + * @ingroup base + */ +template +using AtomicOrLocked = +#if defined(__GNUC__) && __GNUC__ < 5 + // GCC does not implement std::is_trivially_copyable until version 5. + typename std::conditional::value || std::is_pointer::value, std::atomic, Locked>::type; +#else /* defined(__GNUC__) && __GNUC__ < 5 */ + typename std::conditional::value, std::atomic, Locked>::type; +#endif /* defined(__GNUC__) && __GNUC__ < 5 */ + +} + +#endif /* ATOMIC_H */ -- cgit v1.2.3