nuclear@3: /************************************************************************************ nuclear@3: nuclear@3: Filename : OVR_RefCount.cpp nuclear@3: Content : Reference counting implementation nuclear@3: Created : September 19, 2012 nuclear@3: Notes : nuclear@3: nuclear@3: Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. nuclear@3: nuclear@3: Use of this software is subject to the terms of the Oculus license nuclear@3: agreement provided at the time of installation or download, or which nuclear@3: otherwise accompanies this software in either electronic or hard copy form. nuclear@3: nuclear@3: ************************************************************************************/ nuclear@3: nuclear@3: #include "OVR_RefCount.h" nuclear@3: #include "OVR_Atomic.h" nuclear@3: #include "OVR_Log.h" nuclear@3: nuclear@3: namespace OVR { nuclear@3: nuclear@3: #ifdef OVR_CC_ARM nuclear@3: void* ReturnArg0(void* p) nuclear@3: { nuclear@3: return p; nuclear@3: } nuclear@3: #endif nuclear@3: nuclear@3: // ***** Reference Count Base implementation nuclear@3: nuclear@3: RefCountImplCore::~RefCountImplCore() nuclear@3: { nuclear@3: // RefCount can be either 1 or 0 here. nuclear@3: // 0 if Release() was properly called. nuclear@3: // 1 if the object was declared on stack or as an aggregate. nuclear@3: OVR_ASSERT(RefCount <= 1); nuclear@3: } nuclear@3: nuclear@3: #ifdef OVR_BUILD_DEBUG nuclear@3: void RefCountImplCore::reportInvalidDelete(void *pmem) nuclear@3: { nuclear@3: OVR_DEBUG_LOG( nuclear@3: ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); nuclear@3: OVR_ASSERT(0); nuclear@3: } nuclear@3: #endif nuclear@3: nuclear@3: RefCountNTSImplCore::~RefCountNTSImplCore() nuclear@3: { nuclear@3: // RefCount can be either 1 or 0 here. nuclear@3: // 0 if Release() was properly called. nuclear@3: // 1 if the object was declared on stack or as an aggregate. nuclear@3: OVR_ASSERT(RefCount <= 1); nuclear@3: } nuclear@3: nuclear@3: #ifdef OVR_BUILD_DEBUG nuclear@3: void RefCountNTSImplCore::reportInvalidDelete(void *pmem) nuclear@3: { nuclear@3: OVR_DEBUG_LOG( nuclear@3: ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); nuclear@3: OVR_ASSERT(0); nuclear@3: } nuclear@3: #endif nuclear@3: nuclear@3: nuclear@3: // *** Thread-Safe RefCountImpl nuclear@3: nuclear@3: void RefCountImpl::AddRef() nuclear@3: { nuclear@3: AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); nuclear@3: } nuclear@3: void RefCountImpl::Release() nuclear@3: { nuclear@3: if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) nuclear@3: delete this; nuclear@3: } nuclear@3: nuclear@3: // *** Thread-Safe RefCountVImpl w/virtual AddRef/Release nuclear@3: nuclear@3: void RefCountVImpl::AddRef() nuclear@3: { nuclear@3: AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); nuclear@3: } nuclear@3: void RefCountVImpl::Release() nuclear@3: { nuclear@3: if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) nuclear@3: delete this; nuclear@3: } nuclear@3: nuclear@3: // *** NON-Thread-Safe RefCountImpl nuclear@3: nuclear@3: void RefCountNTSImpl::Release() const nuclear@3: { nuclear@3: RefCount--; nuclear@3: if (RefCount == 0) nuclear@3: delete this; nuclear@3: } nuclear@3: nuclear@3: nuclear@3: } // OVR