aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llthread.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llthread.h')
-rw-r--r--linden/indra/llcommon/llthread.h88
1 files changed, 74 insertions, 14 deletions
diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h
index 98d64ef..8708929 100644
--- a/linden/indra/llcommon/llthread.h
+++ b/linden/indra/llcommon/llthread.h
@@ -38,11 +38,28 @@
38#include "llmemory.h" 38#include "llmemory.h"
39 39
40#include "apr_thread_cond.h" 40#include "apr_thread_cond.h"
41#include "aiaprpool.h"
41 42
42class LLThread; 43class LLThread;
43class LLMutex; 44class LLMutex;
44class LLCondition; 45class LLCondition;
45 46
47class LL_COMMON_API AIThreadLocalData
48{
49private:
50 static apr_threadkey_t* sThreadLocalDataKey;
51
52public:
53 // Thread-local memory pool.
54 AIAPRRootPool mRootPool;
55 AIVolatileAPRPool mVolatileAPRPool;
56
57 static void init(void);
58 static void destroy(void* thread_local_data);
59 static void create(LLThread* pthread);
60 static AIThreadLocalData& tldata(void);
61};
62
46class LL_COMMON_API LLThread 63class LL_COMMON_API LLThread
47{ 64{
48public: 65public:
@@ -53,7 +70,7 @@ public:
53 QUITTING= 2 // Someone wants this thread to quit 70 QUITTING= 2 // Someone wants this thread to quit
54 } EThreadStatus; 71 } EThreadStatus;
55 72
56 LLThread(const std::string& name, apr_pool_t *poolp = NULL); 73 LLThread(std::string const& name);
57 virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. 74 virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
58 virtual void shutdown(); // stops the thread 75 virtual void shutdown(); // stops the thread
59 76
@@ -82,7 +99,8 @@ public:
82 // this kicks off the apr thread 99 // this kicks off the apr thread
83 void start(void); 100 void start(void);
84 101
85 apr_pool_t *getAPRPool() { return mAPRPoolp; } 102 // Return thread-local data for the current thread.
103 static AIThreadLocalData& tldata(void) { return AIThreadLocalData::tldata(); }
86 104
87private: 105private:
88 bool mPaused; 106 bool mPaused;
@@ -95,10 +113,11 @@ protected:
95 LLCondition* mRunCondition; 113 LLCondition* mRunCondition;
96 114
97 apr_thread_t *mAPRThreadp; 115 apr_thread_t *mAPRThreadp;
98 apr_pool_t *mAPRPoolp;
99 bool mIsLocalPool;
100 EThreadStatus mStatus; 116 EThreadStatus mStatus;
101 117
118 friend void AIThreadLocalData::create(LLThread* threadp);
119 AIThreadLocalData* mThreadLocalData;
120
102 void setQuitting(); 121 void setQuitting();
103 122
104 // virtual function overridden by subclass -- this will be called when the thread runs 123 // virtual function overridden by subclass -- this will be called when the thread runs
@@ -125,12 +144,9 @@ protected:
125 144
126//============================================================================ 145//============================================================================
127 146
128class LL_COMMON_API LLMutex 147class LL_COMMON_API LLMutexBase
129{ 148{
130public: 149public:
131 LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
132 ~LLMutex();
133
134 void lock() { apr_thread_mutex_lock(mAPRMutexp); } 150 void lock() { apr_thread_mutex_lock(mAPRMutexp); }
135 void unlock() { apr_thread_mutex_unlock(mAPRMutexp); } 151 void unlock() { apr_thread_mutex_unlock(mAPRMutexp); }
136 // Returns true if lock was obtained successfully. 152 // Returns true if lock was obtained successfully.
@@ -139,16 +155,60 @@ public:
139 bool isLocked(); // non-blocking, but does do a lock/unlock so not free 155 bool isLocked(); // non-blocking, but does do a lock/unlock so not free
140 156
141protected: 157protected:
142 apr_thread_mutex_t *mAPRMutexp; 158 // mAPRMutexp is initialized and uninitialized in the derived class.
143 apr_pool_t *mAPRPoolp; 159 apr_thread_mutex_t* mAPRMutexp;
144 bool mIsLocalPool; 160};
161
162class LL_COMMON_API LLMutex : public LLMutexBase
163{
164public:
165 LLMutex(AIAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
166 {
167 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mPool());
168 }
169 ~LLMutex()
170 {
171 llassert(!isLocked()); // better not be locked!
172 apr_thread_mutex_destroy(mAPRMutexp);
173 mAPRMutexp = NULL;
174 }
175
176protected:
177 AIAPRPool mPool;
178};
179
180#if APR_HAS_THREADS
181// No need to use a root pool in this case.
182typedef LLMutex LLMutexRootPool;
183#else // APR_HAS_THREADS
184class LL_COMMON_API LLMutexRootPool : public LLMutexBase
185{
186public:
187 LLMutexRootPool(void)
188 {
189 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mRootPool());
190 }
191 ~LLMutexRootPool()
192 {
193#if APR_POOL_DEBUG
194 // It is allowed to destruct root pools from a different thread.
195 mRootPool.grab_ownership();
196#endif
197 llassert(!isLocked()); // better not be locked!
198 apr_thread_mutex_destroy(mAPRMutexp);
199 mAPRMutexp = NULL;
200 }
201
202protected:
203 AIAPRRootPool mRootPool;
145}; 204};
205#endif // APR_HAS_THREADS
146 206
147// Actually a condition/mutex pair (since each condition needs to be associated with a mutex). 207// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
148class LL_COMMON_API LLCondition : public LLMutex 208class LL_COMMON_API LLCondition : public LLMutex
149{ 209{
150public: 210public:
151 LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. 211 LLCondition(AIAPRPool& parent = LLThread::tldata().mRootPool);
152 ~LLCondition(); 212 ~LLCondition();
153 213
154 void wait(); // blocks 214 void wait(); // blocks
@@ -162,7 +222,7 @@ protected:
162class LL_COMMON_API LLMutexLock 222class LL_COMMON_API LLMutexLock
163{ 223{
164public: 224public:
165 LLMutexLock(LLMutex* mutex) 225 LLMutexLock(LLMutexBase* mutex)
166 { 226 {
167 mMutex = mutex; 227 mMutex = mutex;
168 mMutex->lock(); 228 mMutex->lock();
@@ -172,7 +232,7 @@ public:
172 mMutex->unlock(); 232 mMutex->unlock();
173 } 233 }
174private: 234private:
175 LLMutex* mMutex; 235 LLMutexBase* mMutex;
176}; 236};
177 237
178//============================================================================ 238//============================================================================