diff options
Diffstat (limited to 'indra/llcommon/llrefcount.h')
-rwxr-xr-x[-rw-r--r--] | indra/llcommon/llrefcount.h | 144 |
1 files changed, 120 insertions, 24 deletions
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index a18f6706a9..3836a9b5fb 100644..100755 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -2,37 +2,39 @@ * @file llrefcount.h * @brief Base class for reference counted objects for use with LLPointer * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef LLREFCOUNT_H #define LLREFCOUNT_H #include <boost/noncopyable.hpp> +#include <boost/intrusive_ptr.hpp> +#include "llmutex.h" +#include "llapr.h" + +#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 @@ -49,21 +51,26 @@ protected: public: LLRefCount(); - void ref() const +#if LL_REF_COUNT_DEBUG + void ref() const ; + S32 unref() const ; +#else + inline void ref() const { mRef++; } - S32 unref() const + inline S32 unref() const { llassert(mRef >= 1); - if (0 == --mRef) + if (0 == --mRef) { delete this; return 0; } return mRef; } +#endif //NOTE: when passing around a const LLRefCount object, this can return different results // at different types, since mRef is mutable @@ -74,6 +81,95 @@ public: private: mutable S32 mRef; + +#if LL_REF_COUNT_DEBUG + LLMutex* mMutexp ; + mutable U32 mLockedThreadID ; + mutable BOOL mCrashAtUnlock ; +#endif +}; + + +//============================================================================ + +// see llmemory.h for LLPointer<> definition + +class LL_COMMON_API LLThreadSafeRefCount +{ +public: + static void initThreadSafeRefCount(); // creates sMutex + static void cleanupThreadSafeRefCount(); // destroys sMutex + +private: + static LLMutex* sMutex; + +protected: + virtual ~LLThreadSafeRefCount(); // use unref() + +public: + LLThreadSafeRefCount(); + LLThreadSafeRefCount(const LLThreadSafeRefCount&); + LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) + { + mRef = 0; + return *this; + } + + void ref() + { + mRef++; + } + + void unref() + { + llassert(mRef >= 1); + if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value. + { + // If we hit zero, the caller should be the only smart pointer owning the object and we can delete it. + // It is technically possible for a vanilla pointer to mess this up, or another thread to + // jump in, find this object, create another smart pointer and end up dangling, but if + // the code is that bad and not thread-safe, it's trouble already. + delete this; + } + } + + S32 getNumRefs() const + { + const S32 currentVal = mRef.CurrentValue(); + return currentVal; + } + +private: + LLAtomic32< S32 > mRef; }; +/** + * intrusive pointer support + * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type + */ +/** + * intrusive pointer support for LLThreadSafeRefCount + * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type + */ + +inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p) +{ + p->ref(); +} + +inline void intrusive_ptr_release(LLThreadSafeRefCount* p) +{ + p->unref(); +} + +inline void intrusive_ptr_add_ref(LLRefCount* p) +{ + p->ref(); +} + +inline void intrusive_ptr_release(LLRefCount* p) +{ + p->unref(); +} + #endif |