]> granicus.if.org Git - icinga2/commitdiff
Use C++11 atomics for our intrusive pointers 7008/head
authorAlexander A. Klimov <alexander.klimov@icinga.com>
Mon, 11 Mar 2019 11:05:01 +0000 (12:05 +0100)
committerMichael Friedrich <michael.friedrich@icinga.com>
Tue, 2 Apr 2019 11:54:30 +0000 (13:54 +0200)
lib/base/object.cpp
lib/base/object.hpp

index 4f186628e61e39cd7b1b3ca09c88b6e14909fe44..b00891b4c4f8bfb1ad2e62a79c03ab875757ddc6 100644 (file)
@@ -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 */
index 00f3e0ee2ff6cb3b1e2a5a95e1cb4ec59f6401ef..71e9b0bfa3a83da1916738176a148f9df23a081b 100644 (file)
@@ -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