From d283872da69d616345b0bc5e430484536abc3ee1 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 1 Jun 2014 11:54:07 -0700 Subject: [PATCH] Unify leak checkers --- Sources/Plasma/CoreLib/hsRefCnt.cpp | 76 ++++++++++++++--------------- Sources/Plasma/CoreLib/hsRefCnt.h | 18 +++++-- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/Sources/Plasma/CoreLib/hsRefCnt.cpp b/Sources/Plasma/CoreLib/hsRefCnt.cpp index 6d5d7960..3cf968f0 100644 --- a/Sources/Plasma/CoreLib/hsRefCnt.cpp +++ b/Sources/Plasma/CoreLib/hsRefCnt.cpp @@ -56,12 +56,18 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include #include #include "plFormat.h" -#include "hsWindows.h" -template +// hsDebugMessage can get overridden to dump to a file :( +#ifdef _MSC_VER +# include "hsWindows.h" +# define _LeakDebug(message) OutputDebugString(message) +#else +# define _LeakDebug(message) fputs(message, stderr) +#endif + struct _RefCountLeakCheck { - std::unordered_set<_RefType *> m_refs; + std::unordered_set<_hsRefCnt_Base *> m_refs; unsigned m_added, m_removed; std::mutex m_mutex; @@ -69,47 +75,53 @@ struct _RefCountLeakCheck { std::lock_guard lock(m_mutex); - OutputDebugString(plFormat("Refs tracked: {} created, {} destroyed\n", - m_added, m_removed).c_str()); + _LeakDebug(plFormat("Refs tracked: {} created, {} destroyed\n", + m_added, m_removed).c_str()); if (m_refs.empty()) return; - OutputDebugString(plFormat(" {} objects leaked...\n", m_refs.size()).c_str()); - for (_RefType *ref : m_refs) { - OutputDebugString(plFormat(" 0x{_08x} {}: {} refs remain\n", - (uintptr_t)ref, typeid(*ref).name(), ref->RefCnt()).c_str()); + _LeakDebug(plFormat(" {} objects leaked...\n", m_refs.size()).c_str()); + for (_hsRefCnt_Base *ref : m_refs) { + _LeakDebug(plFormat(" 0x{_08x} {}: {} refs remain\n", + (uintptr_t)ref, typeid(*ref).name(), ref->RefCnt()).c_str()); } } - static _RefCountLeakCheck<_RefType> *_instance() + static _RefCountLeakCheck *_instance() { - static _RefCountLeakCheck<_RefType> s_instance; + static _RefCountLeakCheck s_instance; return &s_instance; } - static void add(_RefType *node) + static void add(_hsRefCnt_Base *ref) { - _RefCountLeakCheck<_RefType> *p = _instance(); - std::lock_guard lock(p->m_mutex); - ++p->m_added; - p->m_refs.insert(node); + _RefCountLeakCheck *this_p = _instance(); + std::lock_guard lock(this_p->m_mutex); + ++this_p->m_added; + this_p->m_refs.insert(ref); } - static void del(_RefType *node) + static void del(_hsRefCnt_Base *ref) { - _RefCountLeakCheck<_RefType> *p = _instance(); - std::lock_guard lock(p->m_mutex); - ++p->m_removed; - p->m_refs.erase(node); + _RefCountLeakCheck *this_p = _instance(); + std::lock_guard lock(this_p->m_mutex); + ++this_p->m_removed; + this_p->m_refs.erase(ref); } }; #endif -hsRefCnt::hsRefCnt(int initRefs) - : fRefCnt(initRefs) +_hsRefCnt_Base::_hsRefCnt_Base(int) { #if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL) - _RefCountLeakCheck::add(this); + _RefCountLeakCheck::add(this); +#endif +} + +_hsRefCnt_Base::~_hsRefCnt_Base() +{ +#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL) + _RefCountLeakCheck::del(this); #endif } @@ -118,10 +130,6 @@ hsRefCnt::~hsRefCnt() #ifdef HS_DEBUGGING hsThrowIfFalse(fRefCnt == 1); #endif - -#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL) - _RefCountLeakCheck::del(this); -#endif } void hsRefCnt::UnRef() @@ -136,23 +144,11 @@ void hsRefCnt::UnRef() --fRefCnt; } -hsAtomicRefCnt::hsAtomicRefCnt(int initRefs) - : fRefCnt(initRefs) -{ -#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL) - _RefCountLeakCheck::add(this); -#endif -} - hsAtomicRefCnt::~hsAtomicRefCnt() { #ifdef HS_DEBUGGING hsThrowIfFalse(fRefCnt == 1); #endif - -#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL) - _RefCountLeakCheck::del(this); -#endif } void hsAtomicRefCnt::UnRef(const char* tag) diff --git a/Sources/Plasma/CoreLib/hsRefCnt.h b/Sources/Plasma/CoreLib/hsRefCnt.h index 45b9eb85..24fee505 100644 --- a/Sources/Plasma/CoreLib/hsRefCnt.h +++ b/Sources/Plasma/CoreLib/hsRefCnt.h @@ -44,12 +44,22 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include -class hsRefCnt { +// 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); + hsRefCnt(int initRefs = 1) : fRefCnt(initRefs) { } virtual ~hsRefCnt(); inline int RefCnt() const { return fRefCnt; } @@ -70,13 +80,13 @@ public: // Thread-safe version. TODO: Evaluate whether this is fast enough to // merge with hsRefCnt above. -class hsAtomicRefCnt +class hsAtomicRefCnt : public _hsRefCnt_Base { private: std::atomic fRefCnt; public: - hsAtomicRefCnt(int initRefs = 1); + hsAtomicRefCnt(int initRefs = 1) : fRefCnt(initRefs) { } virtual ~hsAtomicRefCnt(); inline int RefCnt() const { return fRefCnt; }