diff options
Diffstat (limited to 'indra/llcommon/llthread.h')
-rwxr-xr-x[-rw-r--r--] | indra/llcommon/llthread.h | 185 |
1 files changed, 47 insertions, 138 deletions
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index adef1a9192..6f9ec10fd3 100644..100755 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -2,31 +2,25 @@ * @file llthread.h * @brief Base classes for thread, mutex and condition handling. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&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-2013, Linden Research, Inc. * - * 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 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,13 +30,23 @@ #include "llapp.h" #include "llapr.h" #include "apr_thread_cond.h" +#include "boost/intrusive_ptr.hpp" +#include "llmutex.h" +#include "llrefcount.h" + +LL_COMMON_API void assert_main_thread(); -class LLThread; -class LLMutex; -class LLCondition; +namespace LLTrace +{ + class ThreadRecorder; +} class LL_COMMON_API LLThread { +private: + friend class LLMutex; + static U32 sIDIter; + public: typedef enum e_thread_status { @@ -83,20 +87,30 @@ public: apr_pool_t *getAPRPool() { return mAPRPoolp; } LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; } + U32 getID() const { return mID; } + + // Called by threads *not* created via LLThread to register some + // internal state used by LLMutex. You must call this once early + // in the running thread to prevent collisions with the main thread. + static void registerThreadID(); + private: BOOL mPaused; // static function passed to APR thread creation routine - static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap); + static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap); protected: std::string mName; - LLCondition* mRunCondition; + class LLCondition* mRunCondition; + LLMutex* mDataLock; apr_thread_t *mAPRThreadp; apr_pool_t *mAPRPoolp; BOOL mIsLocalPool; EThreadStatus mStatus; + U32 mID; + LLTrace::ThreadRecorder* mRecorder; //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. @@ -116,138 +130,31 @@ protected: inline void unlockData(); // This is the predicate that decides whether the thread should sleep. - // It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access + // It should only be called with mDataLock locked, since the virtual runCondition() function may need to access // data structures that are thread-unsafe. bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); } // To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following: - // mRunCondition->lock(); + // mDataLock->lock(); // if(!shouldSleep()) // mRunCondition->signal(); - // mRunCondition->unlock(); -}; - -//============================================================================ - -#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) - -class LL_COMMON_API LLMutex -{ -public: - LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex - ~LLMutex(); - - void lock(); // blocks - void unlock(); - bool isLocked(); // non-blocking, but does do a lock/unlock so not free - -protected: - apr_thread_mutex_t *mAPRMutexp; - apr_pool_t *mAPRPoolp; - BOOL mIsLocalPool; -#if MUTEX_DEBUG - std::map<U32, BOOL> mIsLocked; -#endif + // mDataLock->unlock(); }; -// Actually a condition/mutex pair (since each condition needs to be associated with a mutex). -class LL_COMMON_API LLCondition : public LLMutex -{ -public: - LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. - ~LLCondition(); - - void wait(); // blocks - void signal(); - void broadcast(); - -protected: - apr_thread_cond_t *mAPRCondp; -}; - -class LLMutexLock -{ -public: - LLMutexLock(LLMutex* mutex) - { - mMutex = mutex; - mMutex->lock(); - } - ~LLMutexLock() - { - mMutex->unlock(); - } -private: - LLMutex* mMutex; -}; - -//============================================================================ void LLThread::lockData() { - mRunCondition->lock(); + mDataLock->lock(); } void LLThread::unlockData() { - mRunCondition->unlock(); + mDataLock->unlock(); } //============================================================================ -// 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; - -private: - LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented - LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented - -protected: - virtual ~LLThreadSafeRefCount(); // use unref() - -public: - LLThreadSafeRefCount(); - - void ref() - { - if (sMutex) sMutex->lock(); - mRef++; - if (sMutex) sMutex->unlock(); - } - - S32 unref() - { - llassert(mRef >= 1); - if (sMutex) sMutex->lock(); - S32 res = --mRef; - if (sMutex) sMutex->unlock(); - if (0 == res) - { - delete this; - return 0; - } - return res; - } - S32 getNumRefs() const - { - return mRef; - } - -private: - S32 mRef; -}; - -//============================================================================ - // Simple responder for self destructing callbacks // Pure virtual class class LL_COMMON_API LLResponder : public LLThreadSafeRefCount @@ -260,4 +167,6 @@ public: //============================================================================ +extern LL_COMMON_API void assert_main_thread(); + #endif // LL_LLTHREAD_H |