diff options
| -rw-r--r-- | indra/llcommon/llrefcount.cpp | 110 | ||||
| -rw-r--r-- | indra/llcommon/llrefcount.h | 20 | 
2 files changed, 128 insertions, 2 deletions
| diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index 55d0c85cbd..e1876599fc 100644 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp @@ -29,9 +29,25 @@  #include "llerror.h" +#if LL_REF_COUNT_DEBUG +#include "llthread.h" +#include "llapr.h" +#endif +  LLRefCount::LLRefCount(const LLRefCount& other)  :	mRef(0)  { +#if LL_REF_COUNT_DEBUG +	if(gAPRPoolp) +	{ +		mMutexp = new LLMutex(gAPRPoolp) ; +	} +	else +	{ +		mMutexp = NULL ; +	} +	mCrashAtUnlock = FALSE ; +#endif  }  LLRefCount& LLRefCount::operator=(const LLRefCount&) @@ -43,6 +59,17 @@ LLRefCount& LLRefCount::operator=(const LLRefCount&)  LLRefCount::LLRefCount() :  	mRef(0)  { +#if LL_REF_COUNT_DEBUG +	if(gAPRPoolp) +	{ +		mMutexp = new LLMutex(gAPRPoolp) ; +	} +	else +	{ +		mMutexp = NULL ; +	} +	mCrashAtUnlock = FALSE ; +#endif  }  LLRefCount::~LLRefCount() @@ -51,4 +78,87 @@ LLRefCount::~LLRefCount()  	{  		llerrs << "deleting non-zero reference" << llendl;  	} + +#if LL_REF_COUNT_DEBUG +	if(gAPRPoolp) +	{ +		delete mMutexp ; +	} +#endif  } + +#if LL_REF_COUNT_DEBUG +void LLRefCount::ref() const +{  +	if(mMutexp) +	{ +		if(mMutexp->isLocked())  +		{ +			mCrashAtUnlock = TRUE ; +			llerrs << "the mutex is locked by the thread: " << mLockedThreadID  +				<< " Current thread: " << LLThread::currentID() << llendl ; +		} + +		mMutexp->lock() ; +		mLockedThreadID = LLThread::currentID() ; + +		mRef++;  + +		if(mCrashAtUnlock) +		{ +			while(1); //crash here. +		} +		mMutexp->unlock() ; +	} +	else +	{ +		mRef++;  +	} +}  + +S32 LLRefCount::unref() const +{ +	if(mMutexp) +	{ +		if(mMutexp->isLocked())  +		{ +			mCrashAtUnlock = TRUE ; +			llerrs << "the mutex is locked by the thread: " << mLockedThreadID  +				<< " Current thread: " << LLThread::currentID() << llendl ; +		} + +		mMutexp->lock() ; +		mLockedThreadID = LLThread::currentID() ; +		 +		llassert(mRef >= 1); +		if (0 == --mRef)  +		{ +			if(mCrashAtUnlock) +			{ +				while(1); //crash here. +			} +			mMutexp->unlock() ; + +			delete this;  +			return 0; +		} + +		if(mCrashAtUnlock) +		{ +			while(1); //crash here. +		} +		mMutexp->unlock() ; +		return mRef; +	} +	else +	{ +		llassert(mRef >= 1); +		if (0 == --mRef)  +		{ +			delete this;  +			return 0; +		} +		return mRef; +	} +}	 +#endif diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 19f008b15c..693c1c4b83 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -28,6 +28,11 @@  #include <boost/noncopyable.hpp> +#define LL_REF_COUNT_DEBUG 0 +#if LL_REF_COUNT_DEBUG +class LLMutex ; +#endif +  //----------------------------------------------------------------------------  // RefCount objects should generally only be accessed by way of LLPointer<>'s  // see llthread.h for LLThreadSafeRefCount @@ -43,12 +48,16 @@ protected:  public:  	LLRefCount(); -	void ref() const +#if LL_REF_COUNT_DEBUG +	void ref() const ; +	S32 unref() const ; +#else +	inline void LLRefCount::ref() const  	{   		mRef++;   	}  -	S32 unref() const +	inline S32 LLRefCount::unref() const  	{  		llassert(mRef >= 1);  		if (0 == --mRef)  @@ -58,6 +67,7 @@ public:  		}  		return mRef;  	}	 +#endif  	//NOTE: when passing around a const LLRefCount object, this can return different results  	// at different types, since mRef is mutable @@ -68,6 +78,12 @@ public:  private:   	mutable S32	mRef;  + +#if LL_REF_COUNT_DEBUG +	LLMutex*  mMutexp ; +	mutable U32  mLockedThreadID ; +	mutable BOOL mCrashAtUnlock ;  +#endif  };  #endif | 
