1
0
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-18 11:19:10 +00:00

Make hsRefCnt atomic, and merge with hsAtomicRefCnt

This commit is contained in:
2014-06-01 13:29:19 -07:00
parent d283872da6
commit aee2f7f7ca
23 changed files with 90 additions and 98 deletions

View File

@ -67,7 +67,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
struct _RefCountLeakCheck
{
std::unordered_set<_hsRefCnt_Base *> m_refs;
std::unordered_set<hsRefCnt *> m_refs;
unsigned m_added, m_removed;
std::mutex m_mutex;
@ -81,7 +81,7 @@ struct _RefCountLeakCheck
return;
_LeakDebug(plFormat(" {} objects leaked...\n", m_refs.size()).c_str());
for (_hsRefCnt_Base *ref : m_refs) {
for (hsRefCnt *ref : m_refs) {
_LeakDebug(plFormat(" 0x{_08x} {}: {} refs remain\n",
(uintptr_t)ref, typeid(*ref).name(), ref->RefCnt()).c_str());
}
@ -93,7 +93,7 @@ struct _RefCountLeakCheck
return &s_instance;
}
static void add(_hsRefCnt_Base *ref)
static void add(hsRefCnt *ref)
{
_RefCountLeakCheck *this_p = _instance();
std::lock_guard<std::mutex> lock(this_p->m_mutex);
@ -101,7 +101,7 @@ struct _RefCountLeakCheck
this_p->m_refs.insert(ref);
}
static void del(_hsRefCnt_Base *ref)
static void del(hsRefCnt *ref)
{
_RefCountLeakCheck *this_p = _instance();
std::lock_guard<std::mutex> lock(this_p->m_mutex);
@ -111,47 +111,26 @@ struct _RefCountLeakCheck
};
#endif
_hsRefCnt_Base::_hsRefCnt_Base(int)
hsRefCnt::hsRefCnt(int initRefs)
: fRefCnt(initRefs)
{
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
_RefCountLeakCheck::add(this);
#endif
}
_hsRefCnt_Base::~_hsRefCnt_Base()
{
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
_RefCountLeakCheck::del(this);
#endif
}
hsRefCnt::~hsRefCnt()
{
#ifdef HS_DEBUGGING
hsThrowIfFalse(fRefCnt == 1);
#endif
}
void hsRefCnt::UnRef()
{
#ifdef HS_DEBUGGING
hsThrowIfFalse(fRefCnt >= 1);
#endif
if (fRefCnt == 1) // don't decrement if we call delete
delete this;
else
--fRefCnt;
}
hsAtomicRefCnt::~hsAtomicRefCnt()
{
#ifdef HS_DEBUGGING
hsThrowIfFalse(fRefCnt == 1);
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
_RefCountLeakCheck::del(this);
#endif
}
void hsAtomicRefCnt::UnRef(const char* tag)
void hsRefCnt::UnRef(const char* tag)
{
#ifdef HS_DEBUGGING
hsThrowIfFalse(fRefCnt >= 1);
@ -170,7 +149,7 @@ void hsAtomicRefCnt::UnRef(const char* tag)
--fRefCnt;
}
void hsAtomicRefCnt::Ref(const char* tag)
void hsRefCnt::Ref(const char* tag)
{
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_REFS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
if (tag)
@ -182,7 +161,7 @@ void hsAtomicRefCnt::Ref(const char* tag)
++fRefCnt;
}
void hsAtomicRefCnt::TransferRef(const char* oldTag, const char* newTag)
void hsRefCnt::TransferRef(const char* oldTag, const char* newTag)
{
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_REFS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
DEBUG_MSG("Inc %p %s: (xfer)", this, newTag);

View File

@ -44,50 +44,13 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <atomic>
// For easier debugging
class _hsRefCnt_Base
{
public:
_hsRefCnt_Base(int initRefs = 1);
virtual ~_hsRefCnt_Base();
virtual int RefCnt() const = 0;
};
class hsRefCnt : public _hsRefCnt_Base {
private:
int fRefCnt;
public:
hsRefCnt(int initRefs = 1) : fRefCnt(initRefs) { }
virtual ~hsRefCnt();
inline int RefCnt() const { return fRefCnt; }
void UnRef();
inline void Ref() { ++fRefCnt; }
};
#define hsRefCnt_SafeRef(obj) do { if (obj) (obj)->Ref(); } while (0)
#define hsRefCnt_SafeUnRef(obj) do { if (obj) (obj)->UnRef(); } while (0)
#define hsRefCnt_SafeAssign(dst, src) \
do { \
hsRefCnt_SafeRef(src); \
hsRefCnt_SafeUnRef(dst); \
dst = src; \
} while (0)
// Thread-safe version. TODO: Evaluate whether this is fast enough to
// merge with hsRefCnt above.
class hsAtomicRefCnt : public _hsRefCnt_Base
{
class hsRefCnt {
private:
std::atomic<int> fRefCnt;
public:
hsAtomicRefCnt(int initRefs = 1) : fRefCnt(initRefs) { }
virtual ~hsAtomicRefCnt();
hsRefCnt(int initRefs = 1);
virtual ~hsRefCnt();
inline int RefCnt() const { return fRefCnt; }
void UnRef(const char* tag = nullptr);
@ -95,8 +58,26 @@ public:
// Useless, but left here for debugging compatibility with AtomicRef
void TransferRef(const char* oldTag, const char* newTag);
// The stored reference count of an hsRefCnt-derived object should never
// be copied! Therefore, if you want a copyable hsRefCnt-based class, you
// should implement your own copy constructor / assignment operator.
hsRefCnt(const hsRefCnt &) = delete;
hsRefCnt &operator=(const hsRefCnt &) = delete;
};
#define hsRefCnt_SafeRef(obj) do { if (obj) (obj)->Ref(); } while (0)
#define hsRefCnt_SafeUnRef(obj) do { if (obj) (obj)->UnRef(); } while (0)
#define hsRefCnt_SafeAssign(dst, src) \
do { \
hsRefCnt_SafeRef(src); \
hsRefCnt_SafeUnRef(dst); \
dst = src; \
} while (0)
template <class _Ref>
class hsRef
{