Use C++11 atomics for our intrusive pointers

This commit is contained in:
Alexander A. Klimov 2019-03-11 12:05:01 +01:00 committed by Michael Friedrich
parent 58ae29acac
commit cfd0d86b9b
2 changed files with 17 additions and 17 deletions

View 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;
auto previous (object->m_References.fetch_sub(1));
#ifdef _WIN32
refs = InterlockedDecrement(&object->m_References);
#else /* _WIN32 */
refs = __sync_sub_and_fetch(&object->m_References, 1);
#endif /* _WIN32 */
if (unlikely(refs == 0)) {
if (previous == 1u) {
#ifdef I2_LEAK_DEBUG
TypeRemoveObject(object);
#endif /* I2_LEAK_DEBUG */

View 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