summaryrefslogtreecommitdiff
path: root/indra/llcommon/llthread.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llthread.h')
-rw-r--r--indra/llcommon/llthread.h134
1 files changed, 34 insertions, 100 deletions
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index b631b96252..40291a2569 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -29,13 +29,7 @@
#include "llapp.h"
#include "llapr.h"
-#include "llmemory.h"
#include "apr_thread_cond.h"
-#include "llaprpool.h"
-
-#ifdef SHOW_ASSERT
-extern LL_COMMON_API bool is_main_thread(void);
-#endif
class LLThread;
class LLMutex;
@@ -47,22 +41,6 @@ class LLCondition;
#define ll_thread_local __thread
#endif
-class LL_COMMON_API LLThreadLocalData
-{
-private:
- static apr_threadkey_t* sThreadLocalDataKey;
-
-public:
- // Thread-local memory pools.
- LLAPRRootPool mRootPool;
- LLVolatileAPRPool mVolatileAPRPool;
-
- static void init(void);
- static void destroy(void* thread_local_data);
- static void create(LLThread* pthread);
- static LLThreadLocalData& tldata(void);
-};
-
class LL_COMMON_API LLThread
{
private:
@@ -76,7 +54,7 @@ public:
QUITTING= 2 // Someone wants this thread to quit
} EThreadStatus;
- LLThread(std::string const& name);
+ LLThread(const std::string& name, apr_pool_t *poolp = NULL);
virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
virtual void shutdown(); // stops the thread
@@ -91,7 +69,7 @@ public:
// Called from MAIN THREAD.
void pause();
void unpause();
- bool isPaused() { return isStopped() || mPaused; }
+ bool isPaused() { return isStopped() || mPaused == TRUE; }
// Cause the thread to wake up and check its condition
void wake();
@@ -105,11 +83,13 @@ public:
// this kicks off the apr thread
void start(void);
- // Return thread-local data for the current thread.
- static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
+ apr_pool_t *getAPRPool() { return mAPRPoolp; }
+ LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
+
+ U32 getID() const { return mID; }
private:
- bool mPaused;
+ BOOL mPaused;
// static function passed to APR thread creation routine
static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap);
@@ -119,11 +99,15 @@ protected:
LLCondition* mRunCondition;
apr_thread_t *mAPRThreadp;
+ apr_pool_t *mAPRPoolp;
+ BOOL mIsLocalPool;
EThreadStatus mStatus;
U32 mID;
-
- friend void LLThreadLocalData::create(LLThread* threadp);
- LLThreadLocalData* mThreadLocalData;
+
+ //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.
+ // otherwise it will cause severe memory leaking!!! --bao
+ LLVolatileAPRPool *mLocalAPRFilePoolp ;
void setQuitting();
@@ -153,15 +137,7 @@ protected:
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
-#ifdef MUTEX_DEBUG
-// We really shouldn't be using recursive locks. Make sure of that in debug mode.
-#define MUTEX_FLAG APR_THREAD_MUTEX_UNNESTED
-#else
-// Use the fastest platform-optimal lock behavior (can be recursive or non-recursive).
-#define MUTEX_FLAG APR_THREAD_MUTEX_DEFAULT
-#endif
-
-class LL_COMMON_API LLMutexBase
+class LL_COMMON_API LLMutex
{
public:
typedef enum
@@ -169,74 +145,32 @@ public:
NO_THREAD = 0xFFFFFFFF
} e_locking_thread;
- LLMutexBase() ;
-
- void lock() ;
- void unlock() ;
- // Returns true if lock was obtained successfully.
- bool trylock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); }
-
- // non-blocking, but does do a lock/unlock so not free
- bool isLocked() { bool is_not_locked = trylock(); if (is_not_locked) unlock(); return !is_not_locked; }
-
+ LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
+ virtual ~LLMutex();
+
+ void lock(); // blocks
+ void unlock();
+ bool isLocked(); // non-blocking, but does do a lock/unlock so not free
+ U32 lockingThread() const; //get ID of locking thread
+
protected:
- // mAPRMutexp is initialized and uninitialized in the derived class.
- apr_thread_mutex_t* mAPRMutexp;
+ apr_thread_mutex_t *mAPRMutexp;
mutable U32 mCount;
mutable U32 mLockingThread;
-};
-
-class LL_COMMON_API LLMutex : public LLMutexBase
-{
-public:
- LLMutex(LLAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
- {
- apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mPool());
- }
- ~LLMutex()
- {
- //this assertion erroneously triggers whenever an LLCondition is destroyed
- //llassert(!isLocked()); // better not be locked!
- apr_thread_mutex_destroy(mAPRMutexp);
- mAPRMutexp = NULL;
- }
-
-protected:
- LLAPRPool mPool;
-};
-
-#if APR_HAS_THREADS
-// No need to use a root pool in this case.
-typedef LLMutex LLMutexRootPool;
-#else // APR_HAS_THREADS
-class LL_COMMON_API LLMutexRootPool : public LLMutexBase
-{
-public:
- LLMutexRootPool(void)
- {
- apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mRootPool());
- }
- ~LLMutexRootPool()
- {
-#if APR_POOL_DEBUG
- // It is allowed to destruct root pools from a different thread.
- mRootPool.grab_ownership();
+
+ apr_pool_t *mAPRPoolp;
+ BOOL mIsLocalPool;
+
+#if MUTEX_DEBUG
+ std::map<U32, BOOL> mIsLocked;
#endif
- llassert(!isLocked());
- apr_thread_mutex_destroy(mAPRMutexp);
- mAPRMutexp = NULL;
- }
-
-protected:
- LLAPRRootPool mRootPool;
};
-#endif // APR_HAS_THREADS
// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
class LL_COMMON_API LLCondition : public LLMutex
{
public:
- LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool);
+ LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
~LLCondition();
void wait(); // blocks
@@ -247,10 +181,10 @@ protected:
apr_thread_cond_t *mAPRCondp;
};
-class LL_COMMON_API LLMutexLock
+class LLMutexLock
{
public:
- LLMutexLock(LLMutexBase* mutex)
+ LLMutexLock(LLMutex* mutex)
{
mMutex = mutex;
mMutex->lock();
@@ -260,7 +194,7 @@ public:
mMutex->unlock();
}
private:
- LLMutexBase* mMutex;
+ LLMutex* mMutex;
};
//============================================================================