diff options
Diffstat (limited to 'indra/llcommon/llthread.cpp')
-rw-r--r-- | indra/llcommon/llthread.cpp | 149 |
1 files changed, 89 insertions, 60 deletions
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index bdde1b5c48..ed4f9eb376 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -82,9 +82,6 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap local_thread_ID = threadp->mID; #endif - // Create a thread local data. - LLThreadLocalData::create(threadp); - // Run the user supplied function threadp->run(); @@ -97,22 +94,38 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap } -LLThread::LLThread(std::string const& name) : - mPaused(false), +LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : + mPaused(FALSE), mName(name), mAPRThreadp(NULL), - mStatus(STOPPED), - mThreadLocalData(NULL) + mStatus(STOPPED) { - mID = ++sIDIter; //flaw: assume this is called only in the main thread! + // Thread creation probably CAN be paranoid about APR being initialized, if necessary + if (poolp) + { + mIsLocalPool = FALSE; + mAPRPoolp = poolp; + } + else + { + mIsLocalPool = TRUE; + apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread + } + mRunCondition = new LLCondition(mAPRPoolp); - mRunCondition = new LLCondition; + mLocalAPRFilePoolp = NULL ; } LLThread::~LLThread() { shutdown(); + + if(mLocalAPRFilePoolp) + { + delete mLocalAPRFilePoolp ; + mLocalAPRFilePoolp = NULL ; + } } void LLThread::shutdown() @@ -159,8 +172,15 @@ void LLThread::shutdown() delete mRunCondition; mRunCondition = 0; + + if (mIsLocalPool && mAPRPoolp) + { + apr_pool_destroy(mAPRPoolp); + mAPRPoolp = 0; + } } + void LLThread::start() { llassert(isStopped()); @@ -169,7 +189,7 @@ void LLThread::start() mStatus = RUNNING; apr_status_t status = - apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool()); + apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); if(status == APR_SUCCESS) { @@ -194,7 +214,7 @@ void LLThread::pause() if (!mPaused) { // this will cause the thread to stop execution as soon as checkPause() is called - mPaused = true; // Does not need to be atomic since this is only set/unset from the main thread + mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread } } @@ -202,7 +222,7 @@ void LLThread::unpause() { if (mPaused) { - mPaused = false; + mPaused = 0; } wake(); // wake up the thread if necessary @@ -279,76 +299,85 @@ void LLThread::wakeLocked() } } -#ifdef SHOW_ASSERT -// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. -static apr_os_thread_t main_thread_id; -LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } -#endif - -// The thread private handle to access the LLThreadLocalData instance. -apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey; +//============================================================================ -//static -void LLThreadLocalData::init(void) +LLMutex::LLMutex(apr_pool_t *poolp) : + mAPRMutexp(NULL) { - // Only do this once. - if (sThreadLocalDataKey) + //if (poolp) + //{ + // mIsLocalPool = FALSE; + // mAPRPoolp = poolp; + //} + //else { - return; + mIsLocalPool = TRUE; + apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread } + apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); +} - apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &LLThreadLocalData::destroy, LLAPRRootPool::get()()); - ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the - // total number of keys per process {PTHREAD_KEYS_MAX} - // has been exceeded. - - // Create the thread-local data for the main thread (this function is called by the main thread). - LLThreadLocalData::create(NULL); -#ifdef SHOW_ASSERT - // This function is called by the main thread. - main_thread_id = apr_os_thread_current(); +LLMutex::~LLMutex() +{ +#if MUTEX_DEBUG + llassert_always(!isLocked()); // better not be locked! #endif + apr_thread_mutex_destroy(mAPRMutexp); + mAPRMutexp = NULL; + if (mIsLocalPool) + { + apr_pool_destroy(mAPRPoolp); + } } -// This is called once for every thread when the thread is destructed. -//static -void LLThreadLocalData::destroy(void* thread_local_data) + +void LLMutex::lock() { - delete static_cast<LLThreadLocalData*>(thread_local_data); + apr_thread_mutex_lock(mAPRMutexp); +#if MUTEX_DEBUG + // Have to have the lock before we can access the debug info + U32 id = LLThread::currentID(); + if (mIsLocked[id] != FALSE) + llerrs << "Already locked in Thread: " << id << llendl; + mIsLocked[id] = TRUE; +#endif } -//static -void LLThreadLocalData::create(LLThread* threadp) +void LLMutex::unlock() { - LLThreadLocalData* new_tld = new LLThreadLocalData; - if (threadp) - { - threadp->mThreadLocalData = new_tld; - } - apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey); - llassert_always(status == APR_SUCCESS); +#if MUTEX_DEBUG + // Access the debug info while we have the lock + U32 id = LLThread::currentID(); + if (mIsLocked[id] != TRUE) + llerrs << "Not locked in Thread: " << id << llendl; + mIsLocked[id] = FALSE; +#endif + apr_thread_mutex_unlock(mAPRMutexp); } -//static -LLThreadLocalData& LLThreadLocalData::tldata(void) +bool LLMutex::isLocked() { - if (!sThreadLocalDataKey) + apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); + if (APR_STATUS_IS_EBUSY(status)) { - LLThreadLocalData::init(); + return true; + } + else + { + apr_thread_mutex_unlock(mAPRMutexp); + return false; } - - void* data; - apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey); - llassert_always(status == APR_SUCCESS); - return *static_cast<LLThreadLocalData*>(data); } //============================================================================ -LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent) +LLCondition::LLCondition(apr_pool_t *poolp) : + LLMutex(poolp) { - apr_thread_cond_create(&mAPRCondp, mPool()); + // base class (LLMutex) has already ensured that mAPRPoolp is set up. + + apr_thread_cond_create(&mAPRCondp, mAPRPoolp); } @@ -424,7 +453,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() { if (!sMutex) { - sMutex = new LLMutex; + sMutex = new LLMutex(0); } } |