aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llthread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llthread.cpp')
-rw-r--r--linden/indra/llcommon/llthread.cpp117
1 files changed, 66 insertions, 51 deletions
diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp
index 692d6c4..f7732cb 100644
--- a/linden/indra/llcommon/llthread.cpp
+++ b/linden/indra/llcommon/llthread.cpp
@@ -72,8 +72,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
72 // Set thread state to running 72 // Set thread state to running
73 threadp->mStatus = RUNNING; 73 threadp->mStatus = RUNNING;
74 74
75 // Create a thread local APRFile pool. 75 // Create a thread local data.
76 LLVolatileAPRPool::createLocalAPRFilePool(); 76 AIThreadLocalData::create(threadp);
77 77
78 // Run the user supplied function 78 // Run the user supplied function
79 threadp->run(); 79 threadp->run();
@@ -87,24 +87,14 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
87} 87}
88 88
89 89
90LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : 90LLThread::LLThread(std::string const& name) :
91 mPaused(false), 91 mPaused(false),
92 mName(name), 92 mName(name),
93 mAPRThreadp(NULL), 93 mAPRThreadp(NULL),
94 mStatus(STOPPED) 94 mStatus(STOPPED),
95 mThreadLocalData(NULL)
95{ 96{
96 // Thread creation probably CAN be paranoid about APR being initialized, if necessary 97 mRunCondition = new LLCondition;
97 if (poolp)
98 {
99 mIsLocalPool = false;
100 mAPRPoolp = poolp;
101 }
102 else
103 {
104 mIsLocalPool = true;
105 apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
106 }
107 mRunCondition = new LLCondition(mAPRPoolp);
108} 98}
109 99
110 100
@@ -147,24 +137,18 @@ void LLThread::shutdown()
147 if (!isStopped()) 137 if (!isStopped())
148 { 138 {
149 // This thread just wouldn't stop, even though we gave it time 139 // This thread just wouldn't stop, even though we gave it time
150 llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl; 140 llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl;
151 return; 141 return;
152 } 142 }
153 mAPRThreadp = NULL; 143 mAPRThreadp = NULL;
154 } 144 }
155 145
156 delete mRunCondition; 146 delete mRunCondition;
157
158 if (mIsLocalPool)
159 {
160 apr_pool_destroy(mAPRPoolp);
161 }
162} 147}
163 148
164
165void LLThread::start() 149void LLThread::start()
166{ 150{
167 apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); 151 apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
168 152
169 // We won't bother joining 153 // We won't bother joining
170 apr_thread_detach(mAPRThreadp); 154 apr_thread_detach(mAPRThreadp);
@@ -265,38 +249,72 @@ void LLThread::wakeLocked()
265 } 249 }
266} 250}
267 251
268//============================================================================ 252#ifdef SHOW_ASSERT
253// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread.
254static apr_os_thread_t main_thread_id;
255bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); }
256#endif
269 257
270LLMutex::LLMutex(apr_pool_t *poolp) : 258// The thread private handle to access the AIThreadLocalData instance.
271 mAPRMutexp(NULL) 259apr_threadkey_t* AIThreadLocalData::sThreadLocalDataKey;
260
261//static
262void AIThreadLocalData::init(void)
272{ 263{
273 //if (poolp) 264 // Only do this once.
274 //{ 265 if (sThreadLocalDataKey)
275 // mIsLocalPool = false;
276 // mAPRPoolp = poolp;
277 //}
278 //else
279 { 266 {
280 mIsLocalPool = true; 267 return;
281 apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
282 } 268 }
283 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); 269
270 apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &AIThreadLocalData::destroy, AIAPRRootPool::get()());
271 ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the
272 // total number of keys per process {PTHREAD_KEYS_MAX}
273 // has been exceeded.
274
275 // Create the thread-local data for the main thread (this function is called by the main thread).
276 AIThreadLocalData::create(NULL);
277
278#ifdef SHOW_ASSERT
279 // This function is called by the main thread.
280 main_thread_id = apr_os_thread_current();
281#endif
284} 282}
285 283
286LLMutex::~LLMutex() 284// This is called once for every thread when the thread is destructed.
285//static
286void AIThreadLocalData::destroy(void* thread_local_data)
287{ 287{
288#if _DEBUG 288 delete reinterpret_cast<AIThreadLocalData*>(thread_local_data);
289 llassert(!isLocked()); // better not be locked! 289}
290#endif 290
291 apr_thread_mutex_destroy(mAPRMutexp); 291//static
292 mAPRMutexp = NULL; 292void AIThreadLocalData::create(LLThread* threadp)
293 if (mIsLocalPool) 293{
294 AIThreadLocalData* new_tld = new AIThreadLocalData;
295 if (threadp)
294 { 296 {
295 apr_pool_destroy(mAPRPoolp); 297 threadp->mThreadLocalData = new_tld;
296 } 298 }
299 apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey);
300 llassert_always(status == APR_SUCCESS);
297} 301}
298 302
299bool LLMutex::isLocked() 303//static
304AIThreadLocalData& AIThreadLocalData::tldata(void)
305{
306 if (!sThreadLocalDataKey)
307 AIThreadLocalData::init();
308
309 void* data;
310 apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
311 llassert_always(status == APR_SUCCESS);
312 return *static_cast<AIThreadLocalData*>(data);
313}
314
315//============================================================================
316
317bool LLMutexBase::isLocked()
300{ 318{
301 if (!tryLock()) 319 if (!tryLock())
302 { 320 {
@@ -308,12 +326,9 @@ bool LLMutex::isLocked()
308 326
309//============================================================================ 327//============================================================================
310 328
311LLCondition::LLCondition(apr_pool_t *poolp) : 329LLCondition::LLCondition(AIAPRPool& parent) : LLMutex(parent)
312 LLMutex(poolp)
313{ 330{
314 // base class (LLMutex) has already ensured that mAPRPoolp is set up. 331 apr_thread_cond_create(&mAPRCondp, mPool());
315
316 apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
317} 332}
318 333
319LLCondition::~LLCondition() 334LLCondition::~LLCondition()
@@ -349,7 +364,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
349{ 364{
350 if (!sMutex) 365 if (!sMutex)
351 { 366 {
352 sMutex = new LLMutex(0); 367 sMutex = new LLMutex;
353 } 368 }
354} 369}
355 370