From: Alexander A. Klimov <alexander.klimov@icinga.com>
Date: Mon, 11 Mar 2019 11:05:01 +0000 (+0100)
Subject: Use C++11 atomics for our intrusive pointers
X-Git-Tag: v2.11.0-rc1~172^2
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cfd0d86b9b15fa2d5789232dda04dfa309e45cf4;p=icinga2

Use C++11 atomics for our intrusive pointers
---

diff --git a/lib/base/object.cpp b/lib/base/object.cpp
index 4f186628e..b00891b4c 100644
--- a/lib/base/object.cpp
+++ b/lib/base/object.cpp
@@ -21,6 +21,14 @@ static std::map<String, int> l_ObjectCounts;
 static Timer::Ptr l_ObjectCountTimer;
 #endif /* I2_LEAK_DEBUG */
 
+/**
+ * Constructor for the Object class.
+ */
+Object::Object()
+{
+	m_References.store(0);
+}
+
 /**
  * Destructor for the Object class.
  */
@@ -238,28 +246,18 @@ INITIALIZE_ONCE([]() {
 void icinga::intrusive_ptr_add_ref(Object *object)
 {
 #ifdef I2_LEAK_DEBUG
-	if (object->m_References == 0)
+	if (object->m_References.fetch_add(1) == 0u)
 		TypeAddObject(object);
+#else /* I2_LEAK_DEBUG */
+	object->m_References.fetch_add(1);
 #endif /* I2_LEAK_DEBUG */
-
-#ifdef _WIN32
-	InterlockedIncrement(&object->m_References);
-#else /* _WIN32 */
-	__sync_add_and_fetch(&object->m_References, 1);
-#endif /* _WIN32 */
 }
 
 void icinga::intrusive_ptr_release(Object *object)
 {
-	uintptr_t refs;
-
-#ifdef _WIN32
-	refs = InterlockedDecrement(&object->m_References);
-#else /* _WIN32 */
-	refs = __sync_sub_and_fetch(&object->m_References, 1);
-#endif /* _WIN32 */
+	auto previous (object->m_References.fetch_sub(1));
 
-	if (unlikely(refs == 0)) {
+	if (previous == 1u) {
 #ifdef I2_LEAK_DEBUG
 		TypeRemoveObject(object);
 #endif /* I2_LEAK_DEBUG */
diff --git a/lib/base/object.hpp b/lib/base/object.hpp
index 00f3e0ee2..71e9b0bfa 100644
--- a/lib/base/object.hpp
+++ b/lib/base/object.hpp
@@ -6,7 +6,9 @@
 #include "base/i2-base.hpp"
 #include "base/debug.hpp"
 #include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <atomic>
 #include <cstddef>
+#include <cstdint>
 #include <vector>
 
 using boost::intrusive_ptr;
@@ -154,7 +156,7 @@ class Object
 public:
 	DECLARE_PTR_TYPEDEFS(Object);
 
-	Object() = default;
+	Object();
 	virtual ~Object();
 
 	virtual String ToString() const;
@@ -187,7 +189,7 @@ private:
 	Object(const Object& other) = delete;
 	Object& operator=(const Object& rhs) = delete;
 
-	uintptr_t m_References{0};
+	std::atomic<uint_fast64_t> m_References;
 	mutable uintptr_t m_Mutex{0};
 
 #ifdef I2_DEBUG