You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

106 lines
1.6 KiB

#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);
}
}