|
|
- #pragma once
-
- #include "spinlock.h"
- #include <cassert>
-
- namespace vlc
- {
- template<typename TargetClass, bool threadSafe = true> class Refcounted
- {
- using RefcountType = uint32_t;
-
- volatile RefcountType m_refCount = 0;
- Spinlock m_lock;
-
- public:
- RefcountType incRef()
- {
- m_lock.lock();
- auto result = m_refCount;
- m_refCount++;
- m_lock.unlock();
-
- return result;
- }
-
- RefcountType decRef()
- {
- m_lock.lock();
- assert(m_refCount > 0);
- auto result = m_refCount;
- m_refCount--;
- m_lock.unlock();
-
- return result;
- }
-
- RefcountType refs() const
- {
- return m_refCount;
- }
-
- protected:
- Refcounted() = default;
- ~Refcounted() = default;
-
- explicit Refcounted(RefcountType initial_refs) : m_refCount(initial_refs)
- {
-
- }
- };
-
- template<typename TargetClass> class Refcounted<TargetClass, false>
- {
- using RefcountType = uint32_t;
-
- RefcountType m_refCount = 0;
-
- public:
- RefcountType incRef()
- {
- auto result = m_refCount;
- m_refCount++;
-
- return result;
- }
-
- RefcountType decRef()
- {
- assert(m_refCount > 0);
- auto result = m_refCount;
- m_refCount--;
-
- return result;
- }
-
- RefcountType refs() const
- {
- return m_refCount;
- }
-
- protected:
- Refcounted() = default;
- ~Refcounted() = default;
-
- explicit Refcounted(RefcountType initial_refs) : m_refCount(initial_refs)
- {
-
- }
- };
- }
-
- template<typename T> void intrusiveIncRef(vlc::Refcounted<T>* ptr)
- {
- if (ptr)
- {
- ptr->incRef();
- }
- }
-
- template<typename T> void intrusiveDecRef(vlc::Refcounted<T>* ptr)
- {
- if (ptr && ptr->decRef() == 1)
- {
- delete static_cast<T*>(ptr);
- }
- }
|