diff options
author | Jacek Antonelli | 2010-02-08 17:01:00 -0600 |
---|---|---|
committer | Jacek Antonelli | 2010-02-08 17:01:00 -0600 |
commit | d96e672c7fa0cb59ef0c30163326bb40220e745a (patch) | |
tree | 0578f6258788f44f91dbf84eebdb09d994e2a0e5 /linden/indra/llcommon | |
parent | Fixed login screen only allowing 16 chars per name. (diff) | |
download | meta-impy-d96e672c7fa0cb59ef0c30163326bb40220e745a.zip meta-impy-d96e672c7fa0cb59ef0c30163326bb40220e745a.tar.gz meta-impy-d96e672c7fa0cb59ef0c30163326bb40220e745a.tar.bz2 meta-impy-d96e672c7fa0cb59ef0c30163326bb40220e745a.tar.xz |
Ported many APR changes from Snowglobe.
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llcommon/llapr.cpp | 284 | ||||
-rw-r--r-- | linden/indra/llcommon/llapr.h | 47 | ||||
-rw-r--r-- | linden/indra/llcommon/llthread.cpp | 11 | ||||
-rw-r--r-- | linden/indra/llcommon/llthread.h | 6 | ||||
-rw-r--r-- | linden/indra/llcommon/llworkerthread.cpp | 5 |
5 files changed, 175 insertions, 178 deletions
diff --git a/linden/indra/llcommon/llapr.cpp b/linden/indra/llcommon/llapr.cpp index 669afc5..7e3a26c 100644 --- a/linden/indra/llcommon/llapr.cpp +++ b/linden/indra/llcommon/llapr.cpp | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "llapr.h" | 36 | #include "llapr.h" |
37 | 37 | ||
38 | apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool | 38 | apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool |
39 | LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. | ||
40 | apr_thread_mutex_t *gLogMutexp = NULL; | 39 | apr_thread_mutex_t *gLogMutexp = NULL; |
41 | apr_thread_mutex_t *gCallStacksLogMutexp = NULL; | 40 | apr_thread_mutex_t *gCallStacksLogMutexp = NULL; |
42 | 41 | ||
@@ -53,11 +52,9 @@ void ll_init_apr() | |||
53 | // Initialize the logging mutex | 52 | // Initialize the logging mutex |
54 | apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); | 53 | apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); |
55 | apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); | 54 | apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); |
56 | } | ||
57 | 55 | ||
58 | if(!LLAPRFile::sAPRFilePoolp) | 56 | // Initialize thread-local APR pool support. |
59 | { | 57 | LLVolatileAPRPool::initLocalAPRFilePool(); |
60 | LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool() ; | ||
61 | } | 58 | } |
62 | } | 59 | } |
63 | 60 | ||
@@ -87,11 +84,6 @@ void ll_cleanup_apr() | |||
87 | apr_pool_destroy(gAPRPoolp); | 84 | apr_pool_destroy(gAPRPoolp); |
88 | gAPRPoolp = NULL; | 85 | gAPRPoolp = NULL; |
89 | } | 86 | } |
90 | if (LLAPRFile::sAPRFilePoolp) | ||
91 | { | ||
92 | delete LLAPRFile::sAPRFilePoolp ; | ||
93 | LLAPRFile::sAPRFilePoolp = NULL ; | ||
94 | } | ||
95 | apr_terminate(); | 87 | apr_terminate(); |
96 | } | 88 | } |
97 | 89 | ||
@@ -207,6 +199,56 @@ BOOL LLVolatileAPRPool::isFull() | |||
207 | { | 199 | { |
208 | return mNumTotalRef > FULL_VOLATILE_APR_POOL ; | 200 | return mNumTotalRef > FULL_VOLATILE_APR_POOL ; |
209 | } | 201 | } |
202 | |||
203 | #ifdef SHOW_ASSERT | ||
204 | // This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. | ||
205 | static void* gIsMainThread; | ||
206 | bool is_main_thread() { return gIsMainThread == LLVolatileAPRPool::getLocalAPRFilePool(); } | ||
207 | #endif | ||
208 | |||
209 | // The thread private handle to access the LocalAPRFilePool. | ||
210 | apr_threadkey_t* LLVolatileAPRPool::sLocalAPRFilePoolKey; | ||
211 | |||
212 | // This should be called exactly once, before the first call to createLocalAPRFilePool. | ||
213 | // static | ||
214 | void LLVolatileAPRPool::initLocalAPRFilePool() | ||
215 | { | ||
216 | apr_status_t status = apr_threadkey_private_create(&sLocalAPRFilePoolKey, &destroyLocalAPRFilePool, gAPRPoolp); | ||
217 | ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the | ||
218 | // total number of keys per process {PTHREAD_KEYS_MAX} | ||
219 | // has been exceeded. | ||
220 | // Create the thread-local pool for the main thread (this function is called by the main thread). | ||
221 | createLocalAPRFilePool(); | ||
222 | #ifdef SHOW_ASSERT | ||
223 | gIsMainThread = getLocalAPRFilePool(); | ||
224 | #endif | ||
225 | } | ||
226 | |||
227 | // This should be called once for every thread, before it uses getLocalAPRFilePool. | ||
228 | // static | ||
229 | void LLVolatileAPRPool::createLocalAPRFilePool() | ||
230 | { | ||
231 | void* thread_local_data = new LLVolatileAPRPool; | ||
232 | apr_status_t status = apr_threadkey_private_set(thread_local_data, sLocalAPRFilePoolKey); | ||
233 | llassert_always(status == APR_SUCCESS); | ||
234 | } | ||
235 | |||
236 | // This is called once for every thread when the thread is destructed. | ||
237 | // static | ||
238 | void LLVolatileAPRPool::destroyLocalAPRFilePool(void* thread_local_data) | ||
239 | { | ||
240 | delete reinterpret_cast<LLVolatileAPRPool*>(thread_local_data); | ||
241 | } | ||
242 | |||
243 | // static | ||
244 | LLVolatileAPRPool* LLVolatileAPRPool::getLocalAPRFilePool() | ||
245 | { | ||
246 | void* thread_local_data; | ||
247 | apr_status_t status = apr_threadkey_private_get(&thread_local_data, sLocalAPRFilePoolKey); | ||
248 | llassert_always(status == APR_SUCCESS); | ||
249 | return reinterpret_cast<LLVolatileAPRPool*>(thread_local_data); | ||
250 | } | ||
251 | |||
210 | //--------------------------------------------------------------------- | 252 | //--------------------------------------------------------------------- |
211 | // | 253 | // |
212 | // LLScopedLock | 254 | // LLScopedLock |
@@ -251,10 +293,9 @@ void LLScopedLock::unlock() | |||
251 | bool ll_apr_warn_status(apr_status_t status) | 293 | bool ll_apr_warn_status(apr_status_t status) |
252 | { | 294 | { |
253 | if(APR_SUCCESS == status) return false; | 295 | if(APR_SUCCESS == status) return false; |
254 | #ifndef LL_WINDOWS | ||
255 | char buf[MAX_STRING]; /* Flawfinder: ignore */ | 296 | char buf[MAX_STRING]; /* Flawfinder: ignore */ |
256 | LL_WARNS_ONCE("APR") << "APR: " << apr_strerror(status, buf, MAX_STRING) << LL_ENDL; | 297 | apr_strerror(status, buf, MAX_STRING); |
257 | #endif | 298 | LL_WARNS("APR") << "APR: " << buf << LL_ENDL; |
258 | return true; | 299 | return true; |
259 | } | 300 | } |
260 | 301 | ||
@@ -268,10 +309,18 @@ void ll_apr_assert_status(apr_status_t status) | |||
268 | // LLAPRFile functions | 309 | // LLAPRFile functions |
269 | // | 310 | // |
270 | LLAPRFile::LLAPRFile() | 311 | LLAPRFile::LLAPRFile() |
312 | : mFile(NULL), | ||
313 | mCurrentFilePoolp(NULL) | ||
271 | { | 314 | { |
272 | mFile = NULL ; | ||
273 | mCurrentFilePoolp = NULL ; | ||
274 | } | 315 | } |
316 | |||
317 | LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type) | ||
318 | : mFile(NULL), | ||
319 | mCurrentFilePoolp(NULL) | ||
320 | { | ||
321 | open(filename, flags, access_type); | ||
322 | } | ||
323 | |||
275 | LLAPRFile::~LLAPRFile() | 324 | LLAPRFile::~LLAPRFile() |
276 | { | 325 | { |
277 | close() ; | 326 | close() ; |
@@ -295,32 +344,27 @@ apr_status_t LLAPRFile::close() | |||
295 | return ret ; | 344 | return ret ; |
296 | } | 345 | } |
297 | 346 | ||
298 | apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep) | 347 | apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) |
299 | { | 348 | { |
300 | apr_status_t s ; | 349 | llassert_always(!mFile); |
301 | s = open(filename, flags, pool ? pool->getVolatileAPRPool() : NULL, sizep) ; | 350 | llassert_always(!mCurrentFilePoolp); |
302 | |||
303 | if(!mCurrentFilePoolp) | ||
304 | { | ||
305 | mCurrentFilePoolp = pool ; | ||
306 | 351 | ||
307 | if(!mFile) | 352 | // Access the pool and increment it's reference count. |
308 | { | 353 | // The reference count of LLVolatileAPRPool objects will be decremented |
309 | close() ; | 354 | // again in LLAPRFile::close by calling mCurrentFilePoolp->clearVolatileAPRPool(). |
310 | } | 355 | apr_pool_t* pool; |
356 | if (access_type == local) | ||
357 | { | ||
358 | // Use a "volatile" thread-local pool. | ||
359 | mCurrentFilePoolp = LLVolatileAPRPool::getLocalAPRFilePool(); | ||
360 | pool = mCurrentFilePoolp->getVolatileAPRPool(); | ||
311 | } | 361 | } |
312 | 362 | else | |
313 | return s ; | 363 | { |
314 | } | 364 | llassert(is_main_thread()); |
315 | apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool, S32* sizep) | 365 | pool = gAPRPoolp; |
316 | { | 366 | } |
317 | apr_status_t s; | 367 | apr_status_t s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, pool); |
318 | |||
319 | //check if already open some file | ||
320 | llassert_always(!mFile) ; | ||
321 | llassert_always(!mCurrentFilePoolp) ; | ||
322 | |||
323 | s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(pool)); | ||
324 | if (s != APR_SUCCESS || !mFile) | 368 | if (s != APR_SUCCESS || !mFile) |
325 | { | 369 | { |
326 | mFile = NULL ; | 370 | mFile = NULL ; |
@@ -349,17 +393,6 @@ apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr | |||
349 | return s; | 393 | return s; |
350 | } | 394 | } |
351 | 395 | ||
352 | apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool) | ||
353 | { | ||
354 | if(!pool) | ||
355 | { | ||
356 | mCurrentFilePoolp = sAPRFilePoolp ; | ||
357 | return mCurrentFilePoolp->getVolatileAPRPool() ; | ||
358 | } | ||
359 | |||
360 | return pool ; | ||
361 | } | ||
362 | |||
363 | // File I/O | 396 | // File I/O |
364 | S32 LLAPRFile::read(void *buf, S32 nbytes) | 397 | S32 LLAPRFile::read(void *buf, S32 nbytes) |
365 | { | 398 | { |
@@ -369,6 +402,7 @@ S32 LLAPRFile::read(void *buf, S32 nbytes) | |||
369 | apr_status_t s = apr_file_read(mFile, buf, &sz); | 402 | apr_status_t s = apr_file_read(mFile, buf, &sz); |
370 | if (s != APR_SUCCESS) | 403 | if (s != APR_SUCCESS) |
371 | { | 404 | { |
405 | ll_apr_warn_status(s); | ||
372 | return 0; | 406 | return 0; |
373 | } | 407 | } |
374 | else | 408 | else |
@@ -386,6 +420,7 @@ S32 LLAPRFile::write(const void *buf, S32 nbytes) | |||
386 | apr_status_t s = apr_file_write(mFile, buf, &sz); | 420 | apr_status_t s = apr_file_write(mFile, buf, &sz); |
387 | if (s != APR_SUCCESS) | 421 | if (s != APR_SUCCESS) |
388 | { | 422 | { |
423 | ll_apr_warn_status(s); | ||
389 | return 0; | 424 | return 0; |
390 | } | 425 | } |
391 | else | 426 | else |
@@ -405,42 +440,16 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) | |||
405 | //static components of LLAPRFile | 440 | //static components of LLAPRFile |
406 | // | 441 | // |
407 | 442 | ||
408 | //static | 443 | // Used in the static functions below. |
409 | apr_status_t LLAPRFile::close(apr_file_t* file_handle, LLVolatileAPRPool* pool) | 444 | class LLScopedVolatileAPRFilePool { |
410 | { | 445 | private: |
411 | apr_status_t ret = APR_SUCCESS ; | 446 | LLVolatileAPRPool* mPool; |
412 | if(file_handle) | 447 | apr_pool_t* apr_pool; |
413 | { | 448 | public: |
414 | ret = apr_file_close(file_handle); | 449 | LLScopedVolatileAPRFilePool() : mPool(LLVolatileAPRPool::getLocalAPRFilePool()), apr_pool(mPool->getVolatileAPRPool()) { } |
415 | file_handle = NULL ; | 450 | ~LLScopedVolatileAPRFilePool() { mPool->clearVolatileAPRPool(); } |
416 | } | 451 | operator apr_pool_t*() const { return apr_pool; } |
417 | 452 | }; | |
418 | if(pool) | ||
419 | { | ||
420 | pool->clearVolatileAPRPool() ; | ||
421 | } | ||
422 | |||
423 | return ret ; | ||
424 | } | ||
425 | |||
426 | //static | ||
427 | apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags) | ||
428 | { | ||
429 | apr_status_t s; | ||
430 | apr_file_t* file_handle ; | ||
431 | |||
432 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | ||
433 | |||
434 | s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool()); | ||
435 | if (s != APR_SUCCESS || !file_handle) | ||
436 | { | ||
437 | file_handle = NULL ; | ||
438 | close(file_handle, pool) ; | ||
439 | return NULL; | ||
440 | } | ||
441 | |||
442 | return file_handle ; | ||
443 | } | ||
444 | 453 | ||
445 | //static | 454 | //static |
446 | S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) | 455 | S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) |
@@ -464,6 +473,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) | |||
464 | } | 473 | } |
465 | if (s != APR_SUCCESS) | 474 | if (s != APR_SUCCESS) |
466 | { | 475 | { |
476 | ll_apr_warn_status(s); | ||
467 | return -1; | 477 | return -1; |
468 | } | 478 | } |
469 | else | 479 | else |
@@ -474,13 +484,15 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) | |||
474 | } | 484 | } |
475 | 485 | ||
476 | //static | 486 | //static |
477 | S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) | 487 | S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) |
478 | { | 488 | { |
479 | //***************************************** | 489 | apr_file_t* file_handle; |
480 | apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY); | 490 | LLScopedVolatileAPRFilePool pool; |
481 | //***************************************** | 491 | apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); |
482 | if (!file_handle) | 492 | if (s != APR_SUCCESS || !file_handle) |
483 | { | 493 | { |
494 | ll_apr_warn_status(s); | ||
495 | LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL; | ||
484 | return 0; | 496 | return 0; |
485 | } | 497 | } |
486 | 498 | ||
@@ -501,6 +513,8 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb | |||
501 | apr_status_t s = apr_file_read(file_handle, buf, &bytes_read); | 513 | apr_status_t s = apr_file_read(file_handle, buf, &bytes_read); |
502 | if (s != APR_SUCCESS) | 514 | if (s != APR_SUCCESS) |
503 | { | 515 | { |
516 | LL_WARNS("APR") << " Attempting to read filename: " << filename << LL_ENDL; | ||
517 | ll_apr_warn_status(s); | ||
504 | bytes_read = 0; | 518 | bytes_read = 0; |
505 | } | 519 | } |
506 | else | 520 | else |
@@ -509,14 +523,13 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb | |||
509 | } | 523 | } |
510 | } | 524 | } |
511 | 525 | ||
512 | //***************************************** | 526 | apr_file_close(file_handle); |
513 | close(file_handle, pool) ; | 527 | |
514 | //***************************************** | ||
515 | return (S32)bytes_read; | 528 | return (S32)bytes_read; |
516 | } | 529 | } |
517 | 530 | ||
518 | //static | 531 | //static |
519 | S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) | 532 | S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) |
520 | { | 533 | { |
521 | apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; | 534 | apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; |
522 | if (offset < 0) | 535 | if (offset < 0) |
@@ -525,11 +538,13 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n | |||
525 | offset = 0; | 538 | offset = 0; |
526 | } | 539 | } |
527 | 540 | ||
528 | //***************************************** | 541 | apr_file_t* file_handle; |
529 | apr_file_t* file_handle = open(filename, pool, flags); | 542 | LLScopedVolatileAPRFilePool pool; |
530 | //***************************************** | 543 | apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); |
531 | if (!file_handle) | 544 | if (s != APR_SUCCESS || !file_handle) |
532 | { | 545 | { |
546 | ll_apr_warn_status(s); | ||
547 | LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL; | ||
533 | return 0; | 548 | return 0; |
534 | } | 549 | } |
535 | 550 | ||
@@ -549,6 +564,8 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n | |||
549 | apr_status_t s = apr_file_write(file_handle, buf, &bytes_written); | 564 | apr_status_t s = apr_file_write(file_handle, buf, &bytes_written); |
550 | if (s != APR_SUCCESS) | 565 | if (s != APR_SUCCESS) |
551 | { | 566 | { |
567 | LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL; | ||
568 | ll_apr_warn_status(s); | ||
552 | bytes_written = 0; | 569 | bytes_written = 0; |
553 | } | 570 | } |
554 | else | 571 | else |
@@ -557,93 +574,84 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n | |||
557 | } | 574 | } |
558 | } | 575 | } |
559 | 576 | ||
560 | //***************************************** | 577 | apr_file_close(file_handle); |
561 | LLAPRFile::close(file_handle, pool); | ||
562 | //***************************************** | ||
563 | 578 | ||
564 | return (S32)bytes_written; | 579 | return (S32)bytes_written; |
565 | } | 580 | } |
566 | 581 | ||
567 | //static | 582 | //static |
568 | bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool) | 583 | bool LLAPRFile::remove(const std::string& filename) |
569 | { | 584 | { |
570 | apr_status_t s; | 585 | apr_status_t s; |
571 | 586 | ||
572 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | 587 | LLScopedVolatileAPRFilePool pool; |
573 | s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool()); | 588 | s = apr_file_remove(filename.c_str(), pool); |
574 | pool->clearVolatileAPRPool() ; | ||
575 | 589 | ||
576 | if (s != APR_SUCCESS) | 590 | if (s != APR_SUCCESS) |
577 | { | 591 | { |
578 | LL_DEBUGS("APR") << "LLAPRFile::remove failed on file: " << filename << LL_ENDL; | ||
579 | ll_apr_warn_status(s); | 592 | ll_apr_warn_status(s); |
593 | LL_WARNS("APR") << " Attempting to remove filename: " << filename << LL_ENDL; | ||
580 | return false; | 594 | return false; |
581 | } | 595 | } |
582 | return true; | 596 | return true; |
583 | } | 597 | } |
584 | 598 | ||
585 | //static | 599 | //static |
586 | bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool) | 600 | bool LLAPRFile::rename(const std::string& filename, const std::string& newname) |
587 | { | 601 | { |
588 | apr_status_t s; | 602 | apr_status_t s; |
589 | 603 | ||
590 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | 604 | LLScopedVolatileAPRFilePool pool; |
591 | s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool()); | 605 | s = apr_file_rename(filename.c_str(), newname.c_str(), pool); |
592 | pool->clearVolatileAPRPool() ; | ||
593 | 606 | ||
594 | if (s != APR_SUCCESS) | 607 | if (s != APR_SUCCESS) |
595 | { | 608 | { |
596 | LL_DEBUGS("APR") << "LLAPRFile::rename failed on file: " << filename << LL_ENDL; | ||
597 | ll_apr_warn_status(s); | 609 | ll_apr_warn_status(s); |
610 | LL_WARNS("APR") << " Attempting to rename filename: " << filename << LL_ENDL; | ||
598 | return false; | 611 | return false; |
599 | } | 612 | } |
600 | return true; | 613 | return true; |
601 | } | 614 | } |
602 | 615 | ||
603 | //static | 616 | //static |
604 | bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags) | 617 | bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags) |
605 | { | 618 | { |
606 | apr_file_t* apr_file; | 619 | apr_file_t* file_handle; |
607 | apr_status_t s; | 620 | apr_status_t s; |
608 | 621 | ||
609 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | 622 | LLScopedVolatileAPRFilePool pool; |
610 | s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool()); | 623 | s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); |
611 | 624 | ||
612 | if (s != APR_SUCCESS || !apr_file) | 625 | if (s != APR_SUCCESS || !file_handle) |
613 | { | 626 | { |
614 | pool->clearVolatileAPRPool() ; | ||
615 | return false; | 627 | return false; |
616 | } | 628 | } |
617 | else | 629 | else |
618 | { | 630 | { |
619 | apr_file_close(apr_file) ; | 631 | apr_file_close(file_handle); |
620 | pool->clearVolatileAPRPool() ; | ||
621 | return true; | 632 | return true; |
622 | } | 633 | } |
623 | } | 634 | } |
624 | 635 | ||
625 | //static | 636 | //static |
626 | S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool) | 637 | S32 LLAPRFile::size(const std::string& filename) |
627 | { | 638 | { |
628 | apr_file_t* apr_file; | 639 | apr_file_t* file_handle; |
629 | apr_finfo_t info; | 640 | apr_finfo_t info; |
630 | apr_status_t s; | 641 | apr_status_t s; |
631 | 642 | ||
632 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | 643 | LLScopedVolatileAPRFilePool pool; |
633 | s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool()); | 644 | s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool); |
634 | 645 | ||
635 | if (s != APR_SUCCESS || !apr_file) | 646 | if (s != APR_SUCCESS || !file_handle) |
636 | { | 647 | { |
637 | pool->clearVolatileAPRPool() ; | ||
638 | |||
639 | return 0; | 648 | return 0; |
640 | } | 649 | } |
641 | else | 650 | else |
642 | { | 651 | { |
643 | apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file); | 652 | apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, file_handle); |
644 | 653 | ||
645 | apr_file_close(apr_file) ; | 654 | apr_file_close(file_handle) ; |
646 | pool->clearVolatileAPRPool() ; | ||
647 | 655 | ||
648 | if (s == APR_SUCCESS) | 656 | if (s == APR_SUCCESS) |
649 | { | 657 | { |
@@ -657,36 +665,34 @@ S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool) | |||
657 | } | 665 | } |
658 | 666 | ||
659 | //static | 667 | //static |
660 | bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool) | 668 | bool LLAPRFile::makeDir(const std::string& dirname) |
661 | { | 669 | { |
662 | apr_status_t s; | 670 | apr_status_t s; |
663 | 671 | ||
664 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | 672 | LLScopedVolatileAPRFilePool pool; |
665 | s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool()); | 673 | s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); |
666 | pool->clearVolatileAPRPool() ; | ||
667 | 674 | ||
668 | if (s != APR_SUCCESS) | 675 | if (s != APR_SUCCESS) |
669 | { | 676 | { |
670 | LL_DEBUGS("APR") << "LLAPRFile::makeDir failed on file: " << dirname << LL_ENDL; | ||
671 | ll_apr_warn_status(s); | 677 | ll_apr_warn_status(s); |
678 | LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL; | ||
672 | return false; | 679 | return false; |
673 | } | 680 | } |
674 | return true; | 681 | return true; |
675 | } | 682 | } |
676 | 683 | ||
677 | //static | 684 | //static |
678 | bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool) | 685 | bool LLAPRFile::removeDir(const std::string& dirname) |
679 | { | 686 | { |
680 | apr_status_t s; | 687 | apr_status_t s; |
681 | 688 | ||
682 | pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; | 689 | LLScopedVolatileAPRFilePool pool; |
683 | s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool()); | 690 | s = apr_file_remove(dirname.c_str(), pool); |
684 | pool->clearVolatileAPRPool() ; | ||
685 | 691 | ||
686 | if (s != APR_SUCCESS) | 692 | if (s != APR_SUCCESS) |
687 | { | 693 | { |
688 | LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL; | ||
689 | ll_apr_warn_status(s); | 694 | ll_apr_warn_status(s); |
695 | LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL; | ||
690 | return false; | 696 | return false; |
691 | } | 697 | } |
692 | return true; | 698 | return true; |
diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h index 63130a8..7f770b0 100644 --- a/linden/indra/llcommon/llapr.h +++ b/linden/indra/llcommon/llapr.h | |||
@@ -92,7 +92,7 @@ protected: | |||
92 | //which clears memory automatically. | 92 | //which clears memory automatically. |
93 | //so it can not hold static data or data after memory is cleared | 93 | //so it can not hold static data or data after memory is cleared |
94 | // | 94 | // |
95 | class LLVolatileAPRPool : public LLAPRPool | 95 | class LLVolatileAPRPool : protected LLAPRPool |
96 | { | 96 | { |
97 | public: | 97 | public: |
98 | LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); | 98 | LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); |
@@ -104,9 +104,17 @@ public: | |||
104 | 104 | ||
105 | BOOL isFull() ; | 105 | BOOL isFull() ; |
106 | BOOL isEmpty() {return !mNumActiveRef ;} | 106 | BOOL isEmpty() {return !mNumActiveRef ;} |
107 | |||
108 | static void initLocalAPRFilePool(); | ||
109 | static void createLocalAPRFilePool(); | ||
110 | static void destroyLocalAPRFilePool(void* thread_local_data); | ||
111 | static LLVolatileAPRPool* getLocalAPRFilePool(); | ||
112 | |||
107 | private: | 113 | private: |
108 | S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. | 114 | S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. |
109 | S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. | 115 | S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. |
116 | |||
117 | static apr_threadkey_t* sLocalAPRFilePoolKey; | ||
110 | } ; | 118 | } ; |
111 | 119 | ||
112 | /** | 120 | /** |
@@ -192,18 +200,25 @@ typedef LLAtomic32<S32> LLAtomicS32; | |||
192 | // 1, a temperary pool passed to an APRFile function, which is used within this function and only once. | 200 | // 1, a temperary pool passed to an APRFile function, which is used within this function and only once. |
193 | // 2, a global pool. | 201 | // 2, a global pool. |
194 | // | 202 | // |
195 | class LLAPRFile | 203 | |
204 | class LLAPRFile : boost::noncopyable | ||
196 | { | 205 | { |
206 | // make this non copyable since a copy closes the file | ||
197 | private: | 207 | private: |
198 | apr_file_t* mFile ; | 208 | apr_file_t* mFile ; |
199 | LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. | 209 | LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. |
200 | 210 | ||
201 | public: | 211 | public: |
212 | enum access_t { | ||
213 | global, // Use a global pool for long-lived file accesses. This should really only happen from the main thread. | ||
214 | local // Use a thread-local volatile pool for short file accesses. | ||
215 | }; | ||
216 | |||
202 | LLAPRFile() ; | 217 | LLAPRFile() ; |
218 | LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type); | ||
203 | ~LLAPRFile() ; | 219 | ~LLAPRFile() ; |
204 | 220 | ||
205 | apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL); | 221 | apr_status_t open(const std::string& filename, apr_int32_t flags, access_t access_type, S32* sizep = NULL); |
206 | apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, S32* sizep = NULL); | ||
207 | apr_status_t close() ; | 222 | apr_status_t close() ; |
208 | 223 | ||
209 | // Returns actual offset, -1 if seek fails | 224 | // Returns actual offset, -1 if seek fails |
@@ -216,32 +231,24 @@ public: | |||
216 | 231 | ||
217 | apr_file_t* getFileHandle() {return mFile;} | 232 | apr_file_t* getFileHandle() {return mFile;} |
218 | 233 | ||
219 | private: | ||
220 | apr_pool_t* getAPRFilePool(apr_pool_t* pool) ; | ||
221 | |||
222 | // | 234 | // |
223 | //******************************************************************************************************************************* | 235 | //******************************************************************************************************************************* |
224 | //static components | 236 | //static components |
225 | // | 237 | // |
226 | public: | ||
227 | static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist. | ||
228 | |||
229 | private: | 238 | private: |
230 | static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags); | ||
231 | static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ; | ||
232 | static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset); | 239 | static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset); |
233 | public: | 240 | public: |
234 | // returns false if failure: | 241 | // returns false if failure: |
235 | static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL); | 242 | static bool remove(const std::string& filename); |
236 | static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL); | 243 | static bool rename(const std::string& filename, const std::string& newname); |
237 | static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ); | 244 | static bool isExist(const std::string& filename, apr_int32_t flags = APR_READ); |
238 | static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL); | 245 | static S32 size(const std::string& filename); |
239 | static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL); | 246 | static bool makeDir(const std::string& dirname); |
240 | static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL); | 247 | static bool removeDir(const std::string& dirname); |
241 | 248 | ||
242 | // Returns bytes read/written, 0 if read/write fails: | 249 | // Returns bytes read/written, 0 if read/write fails: |
243 | static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); | 250 | static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); |
244 | static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); | 251 | static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); |
245 | //******************************************************************************************************************************* | 252 | //******************************************************************************************************************************* |
246 | }; | 253 | }; |
247 | 254 | ||
diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp index 37b03a4..b39ffb6 100644 --- a/linden/indra/llcommon/llthread.cpp +++ b/linden/indra/llcommon/llthread.cpp | |||
@@ -72,6 +72,9 @@ 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. | ||
76 | LLVolatileAPRPool::createLocalAPRFilePool(); | ||
77 | |||
75 | // Run the user supplied function | 78 | // Run the user supplied function |
76 | threadp->run(); | 79 | threadp->run(); |
77 | 80 | ||
@@ -102,20 +105,12 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : | |||
102 | apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread | 105 | apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread |
103 | } | 106 | } |
104 | mRunCondition = new LLCondition(mAPRPoolp); | 107 | mRunCondition = new LLCondition(mAPRPoolp); |
105 | |||
106 | mLocalAPRFilePoolp = NULL ; | ||
107 | } | 108 | } |
108 | 109 | ||
109 | 110 | ||
110 | LLThread::~LLThread() | 111 | LLThread::~LLThread() |
111 | { | 112 | { |
112 | shutdown(); | 113 | shutdown(); |
113 | |||
114 | if(mLocalAPRFilePoolp) | ||
115 | { | ||
116 | delete mLocalAPRFilePoolp ; | ||
117 | mLocalAPRFilePoolp = NULL ; | ||
118 | } | ||
119 | } | 114 | } |
120 | 115 | ||
121 | void LLThread::shutdown() | 116 | void LLThread::shutdown() |
diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index 457f45b..721b6e7 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h | |||
@@ -83,7 +83,6 @@ public: | |||
83 | void start(void); | 83 | void start(void); |
84 | 84 | ||
85 | apr_pool_t *getAPRPool() { return mAPRPoolp; } | 85 | apr_pool_t *getAPRPool() { return mAPRPoolp; } |
86 | LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; } | ||
87 | 86 | ||
88 | private: | 87 | private: |
89 | bool mPaused; | 88 | bool mPaused; |
@@ -100,11 +99,6 @@ protected: | |||
100 | bool mIsLocalPool; | 99 | bool mIsLocalPool; |
101 | EThreadStatus mStatus; | 100 | EThreadStatus mStatus; |
102 | 101 | ||
103 | //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. | ||
104 | //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. | ||
105 | // otherwise it will cause severe memory leaking!!! --bao | ||
106 | LLVolatileAPRPool *mLocalAPRFilePoolp ; | ||
107 | |||
108 | void setQuitting(); | 102 | void setQuitting(); |
109 | 103 | ||
110 | // virtual function overridden by subclass -- this will be called when the thread runs | 104 | // virtual function overridden by subclass -- this will be called when the thread runs |
diff --git a/linden/indra/llcommon/llworkerthread.cpp b/linden/indra/llcommon/llworkerthread.cpp index 5dda600..68d32db 100644 --- a/linden/indra/llcommon/llworkerthread.cpp +++ b/linden/indra/llcommon/llworkerthread.cpp | |||
@@ -44,11 +44,6 @@ LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : | |||
44 | LLQueuedThread(name, threaded) | 44 | LLQueuedThread(name, threaded) |
45 | { | 45 | { |
46 | mDeleteMutex = new LLMutex(NULL); | 46 | mDeleteMutex = new LLMutex(NULL); |
47 | |||
48 | if(!mLocalAPRFilePoolp) | ||
49 | { | ||
50 | mLocalAPRFilePoolp = new LLVolatileAPRPool() ; | ||
51 | } | ||
52 | } | 47 | } |
53 | 48 | ||
54 | LLWorkerThread::~LLWorkerThread() | 49 | LLWorkerThread::~LLWorkerThread() |