PageRenderTime 24ms CodeModel.GetById 12ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llrefcount.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 164 lines | 121 code | 17 blank | 26 comment | 16 complexity | 62ece9e1b388b3d6b8b1c0500c16fcd5 MD5 | raw file
  1/** 
  2 * @file llrefcount.cpp
  3 * @brief Base class for reference counted objects for use with LLPointer
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26#include "linden_common.h"
 27
 28#include "llrefcount.h"
 29
 30#include "llerror.h"
 31
 32#if LL_REF_COUNT_DEBUG
 33#include "llthread.h"
 34#include "llapr.h"
 35#endif
 36
 37LLRefCount::LLRefCount(const LLRefCount& other)
 38:	mRef(0)
 39{
 40#if LL_REF_COUNT_DEBUG
 41	if(gAPRPoolp)
 42	{
 43		mMutexp = new LLMutex(gAPRPoolp) ;
 44	}
 45	else
 46	{
 47		mMutexp = NULL ;
 48	}
 49	mCrashAtUnlock = FALSE ;
 50#endif
 51}
 52
 53LLRefCount& LLRefCount::operator=(const LLRefCount&)
 54{
 55	// do nothing, since ref count is specific to *this* reference
 56	return *this;
 57}
 58
 59LLRefCount::LLRefCount() :
 60	mRef(0)
 61{
 62#if LL_REF_COUNT_DEBUG
 63	if(gAPRPoolp)
 64	{
 65		mMutexp = new LLMutex(gAPRPoolp) ;
 66	}
 67	else
 68	{
 69		mMutexp = NULL ;
 70	}
 71	mCrashAtUnlock = FALSE ;
 72#endif
 73}
 74
 75LLRefCount::~LLRefCount()
 76{ 
 77	if (mRef != 0)
 78	{
 79		llerrs << "deleting non-zero reference" << llendl;
 80	}
 81
 82#if LL_REF_COUNT_DEBUG
 83	if(gAPRPoolp)
 84	{
 85		delete mMutexp ;
 86	}
 87#endif
 88}
 89
 90#if LL_REF_COUNT_DEBUG
 91void LLRefCount::ref() const
 92{ 
 93	if(mMutexp)
 94	{
 95		if(mMutexp->isLocked()) 
 96		{
 97			mCrashAtUnlock = TRUE ;
 98			llerrs << "the mutex is locked by the thread: " << mLockedThreadID 
 99				<< " Current thread: " << LLThread::currentID() << llendl ;
100		}
101
102		mMutexp->lock() ;
103		mLockedThreadID = LLThread::currentID() ;
104
105		mRef++; 
106
107		if(mCrashAtUnlock)
108		{
109			while(1); //crash here.
110		}
111		mMutexp->unlock() ;
112	}
113	else
114	{
115		mRef++; 
116	}
117} 
118
119S32 LLRefCount::unref() const
120{
121	if(mMutexp)
122	{
123		if(mMutexp->isLocked()) 
124		{
125			mCrashAtUnlock = TRUE ;
126			llerrs << "the mutex is locked by the thread: " << mLockedThreadID 
127				<< " Current thread: " << LLThread::currentID() << llendl ;
128		}
129
130		mMutexp->lock() ;
131		mLockedThreadID = LLThread::currentID() ;
132		
133		llassert(mRef >= 1);
134		if (0 == --mRef) 
135		{
136			if(mCrashAtUnlock)
137			{
138				while(1); //crash here.
139			}
140			mMutexp->unlock() ;
141
142			delete this; 
143			return 0;
144		}
145
146		if(mCrashAtUnlock)
147		{
148			while(1); //crash here.
149		}
150		mMutexp->unlock() ;
151		return mRef;
152	}
153	else
154	{
155		llassert(mRef >= 1);
156		if (0 == --mRef) 
157		{
158			delete this; 
159			return 0;
160		}
161		return mRef;
162	}
163}	
164#endif