summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/contributions.txt9
-rw-r--r--indra/llaudio/llaudioengine_fmod.cpp2
-rw-r--r--indra/llaudio/llvorbisencode.cpp9
-rw-r--r--indra/llcharacter/llbvhloader.cpp3
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp3
-rw-r--r--indra/llcharacter/llstatemachine.cpp3
-rw-r--r--indra/llcommon/CMakeLists.txt3
-rw-r--r--indra/llcommon/llapp.cpp4
-rw-r--r--indra/llcommon/llapr.cpp445
-rw-r--r--indra/llcommon/llapr.h107
-rw-r--r--indra/llcommon/llaprpool.cpp202
-rw-r--r--indra/llcommon/llaprpool.h256
-rw-r--r--indra/llcommon/llcommon.cpp13
-rw-r--r--indra/llcommon/llcommon.h2
-rw-r--r--indra/llcommon/llerror.cpp3
-rw-r--r--indra/llcommon/llerror.h1
-rw-r--r--indra/llcommon/llfixedbuffer.cpp3
-rw-r--r--indra/llcommon/llscopedvolatileaprpool.h52
-rw-r--r--indra/llcommon/llthread.cpp151
-rw-r--r--indra/llcommon/llthread.h124
-rw-r--r--indra/llcommon/llthreadsafequeue.cpp15
-rw-r--r--indra/llcommon/llthreadsafequeue.h16
-rw-r--r--indra/llcommon/llworkerthread.cpp8
-rw-r--r--indra/llcommon/llworkerthread.h3
-rw-r--r--indra/llcrashlogger/llcrashlogger.cpp3
-rw-r--r--indra/llimage/llimage.cpp8
-rw-r--r--indra/llimage/llimagedimensionsinfo.cpp2
-rw-r--r--indra/llimage/llimagej2c.cpp3
-rw-r--r--indra/llimage/llimageworker.cpp8
-rw-r--r--indra/llimage/llimageworker.h2
-rw-r--r--indra/llmath/llvolumemgr.cpp4
-rw-r--r--indra/llmessage/llares.cpp17
-rw-r--r--indra/llmessage/llcurl.cpp2
-rw-r--r--indra/llmessage/lliohttpserver.cpp10
-rw-r--r--indra/llmessage/lliohttpserver.h2
-rw-r--r--indra/llmessage/lliosocket.cpp99
-rw-r--r--indra/llmessage/lliosocket.h33
-rw-r--r--indra/llmessage/llmail.cpp17
-rw-r--r--indra/llmessage/llmail.h4
-rw-r--r--indra/llmessage/llpumpio.cpp74
-rw-r--r--indra/llmessage/llpumpio.h31
-rw-r--r--indra/llmessage/llurlrequest.cpp25
-rw-r--r--indra/llmessage/message.cpp17
-rw-r--r--indra/llmessage/tests/networkio.h9
-rw-r--r--indra/llplugin/llplugininstance.cpp6
-rw-r--r--indra/llplugin/llplugininstance.h2
-rw-r--r--indra/llplugin/llpluginmessagepipe.cpp2
-rw-r--r--indra/llplugin/llpluginprocesschild.cpp2
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp57
-rw-r--r--indra/llplugin/llpluginprocessparent.h2
-rw-r--r--indra/llplugin/llpluginsharedmemory.cpp9
-rw-r--r--indra/llplugin/llpluginsharedmemory.h3
-rw-r--r--indra/llplugin/slplugin/slplugin.cpp4
-rw-r--r--indra/llvfs/lllfsthread.cpp10
-rw-r--r--indra/llvfs/llvfs.cpp5
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer.h1
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp15
-rw-r--r--indra/media_plugins/webkit/linux_volume_catcher.cpp14
-rw-r--r--indra/newview/llappviewer.cpp47
-rw-r--r--indra/newview/llappviewer.h2
-rw-r--r--indra/newview/llappviewerlinux.cpp1
-rw-r--r--indra/newview/llappviewerlinux_api_dbus.cpp14
-rw-r--r--indra/newview/llappviewermacosx.cpp1
-rw-r--r--indra/newview/llfloateranimpreview.cpp3
-rw-r--r--indra/newview/llmainlooprepeater.cpp2
-rw-r--r--indra/newview/lltexturecache.cpp61
-rw-r--r--indra/newview/lltexturecache.h3
-rw-r--r--indra/newview/lltexturefetch.cpp3
-rw-r--r--indra/newview/llviewermenufile.cpp3
-rw-r--r--indra/newview/llvoavatar.cpp3
-rw-r--r--indra/newview/llvocache.cpp54
-rw-r--r--indra/newview/llvocache.h5
-rw-r--r--indra/newview/llvoicevivox.cpp2
-rw-r--r--indra/newview/llwatchdog.cpp4
-rw-r--r--indra/newview/tests/llworldmap_test.cpp1
-rw-r--r--indra/test/lltemplatemessagebuilder_tut.cpp2
-rw-r--r--indra/test/message_tut.cpp2
-rw-r--r--indra/test/test.cpp17
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.cpp4
-rw-r--r--indra/viewer_components/updater/llupdateinstaller.cpp4
80 files changed, 1097 insertions, 1080 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 8765240caa..03e4978dd0 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -61,11 +61,15 @@ Aimee Trescothick
Alejandro Rosenthal
VWR-1184
Aleric Inglewood
+ SNOW-84
SNOW-240
+ SNOW-477
SNOW-522
SNOW-626
+ SNOW-744
SNOW-756
SNOW-764
+ SNOW-766
VWR-10001
VWR-10579
VWR-10759
@@ -86,11 +90,8 @@ Aleric Inglewood
VWR-24321
VWR-24354
VWR-24519
- SNOW-84
- SNOW-477
- SNOW-744
- SNOW-766
STORM-163
+ STORM-864
Ales Beaumont
VWR-9352
SNOW-240
diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp
index a40de9fa68..88dfdb9c24 100644
--- a/indra/llaudio/llaudioengine_fmod.cpp
+++ b/indra/llaudio/llaudioengine_fmod.cpp
@@ -673,7 +673,7 @@ bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
return false;
}
- if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
+ if (!LLAPRFile::isExist(filename, LL_APR_RPB))
{
// File not found, abort.
return false;
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 0e0c80a456..44eeea0ca4 100644
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -82,8 +82,7 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
error_msg.clear();
//********************************
- LLAPRFile infile ;
- infile.open(in_fname,LL_APR_RB);
+ LLAPRFile infile(in_fname, LL_APR_RB);
//********************************
if (!infile.getFileHandle())
{
@@ -233,8 +232,7 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
S32 data_left = 0;
- LLAPRFile infile ;
- infile.open(in_fname,LL_APR_RB);
+ LLAPRFile infile(in_fname,LL_APR_RB);
if (!infile.getFileHandle())
{
llwarns << "Couldn't open temporary ogg file for writing: " << in_fname
@@ -242,8 +240,7 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
return(LLVORBISENC_SOURCE_OPEN_ERR);
}
- LLAPRFile outfile ;
- outfile.open(out_fname,LL_APR_WPB);
+ LLAPRFile outfile(out_fname, LL_APR_WPB);
if (!outfile.getFileHandle())
{
llwarns << "Couldn't open upload sound file for reading: " << in_fname
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index 532a2c1b0d..a39a344684 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -219,8 +219,7 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
//--------------------------------------------------------------------
std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
- LLAPRFile infile ;
- infile.open(path, LL_APR_R);
+ LLAPRFile infile(path, LL_APR_R);
apr_file_t *fp = infile.getFileHandle();
if (!fp)
return E_ST_NO_XLT_FILE;
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
index 82fe8971f5..c3d5dec875 100644
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
@@ -351,8 +351,7 @@ BOOL LLKeyframeMotionParam::loadMotions()
// open the file
//-------------------------------------------------------------------------
S32 fileSize = 0;
- LLAPRFile infile ;
- infile.open(path, LL_APR_R, NULL, &fileSize);
+ LLAPRFile infile(path, LL_APR_R, &fileSize);
apr_file_t* fp = infile.getFileHandle() ;
if (!fp || fileSize == 0)
{
diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp
index e0454131a5..dcc4ff5f0e 100644
--- a/indra/llcharacter/llstatemachine.cpp
+++ b/indra/llcharacter/llstatemachine.cpp
@@ -204,8 +204,7 @@ LLFSMState* LLStateDiagram::getState(U32 state_id)
BOOL LLStateDiagram::saveDotFile(const std::string& filename)
{
- LLAPRFile outfile ;
- outfile.open(filename, LL_APR_W);
+ LLAPRFile outfile(filename, LL_APR_W);
apr_file_t* dot_file = outfile.getFileHandle() ;
if (!dot_file)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 9342a22d46..d5b0a67533 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -32,6 +32,7 @@ set(llcommon_SOURCE_FILES
llallocator_heap_profile.cpp
llapp.cpp
llapr.cpp
+ llaprpool.cpp
llassettype.cpp
llavatarname.cpp
llbase32.cpp
@@ -80,6 +81,7 @@ set(llcommon_SOURCE_FILES
llrand.cpp
llrefcount.cpp
llrun.cpp
+ llscopedvolatileaprpool.h
llsd.cpp
llsdserialize.cpp
llsdserialize_xml.cpp
@@ -121,6 +123,7 @@ set(llcommon_HEADER_FILES
llavatarname.h
llapp.h
llapr.h
+ llaprpool.h
llassettype.h
llassoclist.h
llavatarconstants.h
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 39daefd1ad..e5bd2bfa3d 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -136,10 +136,6 @@ void LLApp::commonCtor()
mOptions.append(sd);
}
- // Make sure we clean up APR when we exit
- // Don't need to do this if we're cleaning up APR in the destructor
- //atexit(ll_cleanup_apr);
-
// Set the application to this instance.
sApplication = this;
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index d1c44c9403..1e4a51102e 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -29,212 +29,8 @@
#include "linden_common.h"
#include "llapr.h"
#include "apr_dso.h"
+#include "llscopedvolatileaprpool.h"
-apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
-LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
-apr_thread_mutex_t *gLogMutexp = NULL;
-apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
-
-const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
-
-void ll_init_apr()
-{
- if (!gAPRPoolp)
- {
- // Initialize APR and create the global pool
- apr_initialize();
- apr_pool_create(&gAPRPoolp, NULL);
-
- // Initialize the logging mutex
- apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
- apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
- }
-
- if(!LLAPRFile::sAPRFilePoolp)
- {
- LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
- }
-}
-
-
-void ll_cleanup_apr()
-{
- LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
-
- if (gLogMutexp)
- {
- // Clean up the logging mutex
-
- // All other threads NEED to be done before we clean up APR, so this is okay.
- apr_thread_mutex_destroy(gLogMutexp);
- gLogMutexp = NULL;
- }
- if (gCallStacksLogMutexp)
- {
- // Clean up the logging mutex
-
- // All other threads NEED to be done before we clean up APR, so this is okay.
- apr_thread_mutex_destroy(gCallStacksLogMutexp);
- gCallStacksLogMutexp = NULL;
- }
- if (gAPRPoolp)
- {
- apr_pool_destroy(gAPRPoolp);
- gAPRPoolp = NULL;
- }
- if (LLAPRFile::sAPRFilePoolp)
- {
- delete LLAPRFile::sAPRFilePoolp ;
- LLAPRFile::sAPRFilePoolp = NULL ;
- }
- apr_terminate();
-}
-
-//
-//
-//LLAPRPool
-//
-LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
- : mParent(parent),
- mReleasePoolFlag(releasePoolFlag),
- mMaxSize(size),
- mPool(NULL)
-{
- createAPRPool() ;
-}
-
-LLAPRPool::~LLAPRPool()
-{
- releaseAPRPool() ;
-}
-
-void LLAPRPool::createAPRPool()
-{
- if(mPool)
- {
- return ;
- }
-
- mStatus = apr_pool_create(&mPool, mParent);
- ll_apr_warn_status(mStatus) ;
-
- if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
- {
- apr_allocator_t *allocator = apr_pool_allocator_get(mPool);
- if (allocator)
- {
- apr_allocator_max_free_set(allocator, mMaxSize) ;
- }
- }
-}
-
-void LLAPRPool::releaseAPRPool()
-{
- if(!mPool)
- {
- return ;
- }
-
- if(!mParent || mReleasePoolFlag)
- {
- apr_pool_destroy(mPool) ;
- mPool = NULL ;
- }
-}
-
-//virtual
-apr_pool_t* LLAPRPool::getAPRPool()
-{
- return mPool ;
-}
-
-LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
- : LLAPRPool(parent, size, releasePoolFlag),
- mNumActiveRef(0),
- mNumTotalRef(0),
- mMutexPool(NULL),
- mMutexp(NULL)
-{
- //create mutex
- if(!is_local) //not a local apr_pool, that is: shared by multiple threads.
- {
- apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex
- apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);
- }
-}
-
-LLVolatileAPRPool::~LLVolatileAPRPool()
-{
- //delete mutex
- if(mMutexp)
- {
- apr_thread_mutex_destroy(mMutexp);
- apr_pool_destroy(mMutexPool);
- }
-}
-
-//
-//define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
-//
-//virtual
-apr_pool_t* LLVolatileAPRPool::getAPRPool()
-{
- return LLVolatileAPRPool::getVolatileAPRPool() ;
-}
-
-apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
-{
- LLScopedLock lock(mMutexp) ;
-
- mNumTotalRef++ ;
- mNumActiveRef++ ;
-
- if(!mPool)
- {
- createAPRPool() ;
- }
-
- return mPool ;
-}
-
-void LLVolatileAPRPool::clearVolatileAPRPool()
-{
- LLScopedLock lock(mMutexp) ;
-
- if(mNumActiveRef > 0)
- {
- mNumActiveRef--;
- if(mNumActiveRef < 1)
- {
- if(isFull())
- {
- mNumTotalRef = 0 ;
-
- //destroy the apr_pool.
- releaseAPRPool() ;
- }
- else
- {
- //This does not actually free the memory,
- //it just allows the pool to re-use this memory for the next allocation.
- apr_pool_clear(mPool) ;
- }
- }
- }
- else
- {
- llassert_always(mNumActiveRef > 0) ;
- }
-
- //paranoia check if the pool is jammed.
- //will remove the check before going to release.
- llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
-}
-
-BOOL LLVolatileAPRPool::isFull()
-{
- return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
-}
//---------------------------------------------------------------------
//
// LLScopedLock
@@ -313,15 +109,17 @@ void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle)
//
LLAPRFile::LLAPRFile()
: mFile(NULL),
- mCurrentFilePoolp(NULL)
+ mVolatileFilePoolp(NULL),
+ mRegularFilePoolp(NULL)
{
}
-LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool)
+LLAPRFile::LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep, access_t access_type)
: mFile(NULL),
- mCurrentFilePoolp(NULL)
+ mVolatileFilePoolp(NULL),
+ mRegularFilePoolp(NULL)
{
- open(filename, flags, pool);
+ open(filename, flags, access_type, sizep);
}
LLAPRFile::~LLAPRFile()
@@ -338,36 +136,58 @@ apr_status_t LLAPRFile::close()
mFile = NULL ;
}
- if(mCurrentFilePoolp)
+ if (mVolatileFilePoolp)
{
- mCurrentFilePoolp->clearVolatileAPRPool() ;
- mCurrentFilePoolp = NULL ;
+ mVolatileFilePoolp->clearVolatileAPRPool() ;
+ mVolatileFilePoolp = NULL ;
+ }
+
+ if (mRegularFilePoolp)
+ {
+ delete mRegularFilePoolp;
+ mRegularFilePoolp = NULL;
}
return ret ;
}
-apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep)
+apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep)
{
- apr_status_t s ;
-
- //check if already open some file
- llassert_always(!mFile) ;
- llassert_always(!mCurrentFilePoolp) ;
-
- apr_pool_t* apr_pool = pool ? pool->getVolatileAPRPool() : NULL ;
- s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(apr_pool));
+ llassert_always(!mFile);
+ llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp);
- if (s != APR_SUCCESS || !mFile)
+ apr_status_t status;
+ {
+ apr_pool_t* apr_file_open_pool; // The use of apr_pool_t is OK here.
+ // This is a temporary variable for a pool that is passed directly to apr_file_open below.
+ if (access_type == short_lived)
+ {
+ // Use a "volatile" thread-local pool.
+ mVolatileFilePoolp = &LLThreadLocalData::tldata().mVolatileAPRPool;
+ // Access the pool and increment its reference count.
+ // The reference count of LLVolatileAPRPool objects will be decremented
+ // again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool().
+ apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool();
+ }
+ else
+ {
+ mRegularFilePoolp = new LLAPRPool(LLThreadLocalData::tldata().mRootPool);
+ apr_file_open_pool = (*mRegularFilePoolp)();
+ }
+ status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool);
+ }
+ if (status != APR_SUCCESS || !mFile)
{
mFile = NULL ;
-
+ close() ;
if (sizep)
{
*sizep = 0;
}
+ return status;
}
- else if (sizep)
+
+ if (sizep)
{
S32 file_size = 0;
apr_off_t offset = 0;
@@ -381,49 +201,7 @@ apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLV
*sizep = file_size;
}
- if(!mCurrentFilePoolp)
- {
- mCurrentFilePoolp = pool ;
-
- if(!mFile)
- {
- close() ;
- }
- }
-
- return s ;
-}
-
-//use gAPRPoolp.
-apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool)
-{
- apr_status_t s;
-
- //check if already open some file
- llassert_always(!mFile) ;
- llassert_always(!mCurrentFilePoolp) ;
- llassert_always(use_global_pool) ; //be aware of using gAPRPoolp.
-
- s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp);
- if (s != APR_SUCCESS || !mFile)
- {
- mFile = NULL ;
- close() ;
- return s;
- }
-
- return s;
-}
-
-apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
-{
- if(!pool)
- {
- mCurrentFilePoolp = sAPRFilePoolp ;
- return mCurrentFilePoolp->getVolatileAPRPool() ;
- }
-
- return pool ;
+ return status;
}
// File I/O
@@ -482,45 +260,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
//
//static
-apr_status_t LLAPRFile::close(apr_file_t* file_handle, LLVolatileAPRPool* pool)
-{
- apr_status_t ret = APR_SUCCESS ;
- if(file_handle)
- {
- ret = apr_file_close(file_handle);
- file_handle = NULL ;
- }
-
- if(pool)
- {
- pool->clearVolatileAPRPool() ;
- }
-
- return ret ;
-}
-
-//static
-apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
-{
- apr_status_t s;
- apr_file_t* file_handle ;
-
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-
- s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
- if (s != APR_SUCCESS || !file_handle)
- {
- ll_apr_warn_status(s);
- LL_WARNS("APR") << " Attempting to open filename: " << filename << LL_ENDL;
- file_handle = NULL ;
- close(file_handle, pool) ;
- return NULL;
- }
-
- return file_handle ;
-}
-
-//static
S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
{
if(!file_handle)
@@ -553,13 +292,15 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
}
//static
-S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
+S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
{
- //*****************************************
- apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY);
- //*****************************************
- if (!file_handle)
+ apr_file_t* file_handle;
+ LLScopedVolatileAPRPool pool;
+ apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool);
+ if (s != APR_SUCCESS || !file_handle)
{
+ ll_apr_warn_status(s);
+ LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
return 0;
}
@@ -589,14 +330,13 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
}
}
- //*****************************************
- close(file_handle, pool) ;
- //*****************************************
+ apr_file_close(file_handle);
+
return (S32)bytes_read;
}
//static
-S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
+S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
{
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
if (offset < 0)
@@ -605,11 +345,13 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
offset = 0;
}
- //*****************************************
- apr_file_t* file_handle = open(filename, pool, flags);
- //*****************************************
- if (!file_handle)
+ apr_file_t* file_handle;
+ LLScopedVolatileAPRPool pool;
+ apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
+ if (s != APR_SUCCESS || !file_handle)
{
+ ll_apr_warn_status(s);
+ LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
return 0;
}
@@ -639,21 +381,18 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
}
}
- //*****************************************
- LLAPRFile::close(file_handle, pool);
- //*****************************************
+ apr_file_close(file_handle);
return (S32)bytes_written;
}
//static
-bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
+bool LLAPRFile::remove(const std::string& filename)
{
apr_status_t s;
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
- s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool());
- pool->clearVolatileAPRPool() ;
+ LLScopedVolatileAPRPool pool;
+ s = apr_file_remove(filename.c_str(), pool);
if (s != APR_SUCCESS)
{
@@ -665,13 +404,12 @@ bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
}
//static
-bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
+bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
{
apr_status_t s;
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
- s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool());
- pool->clearVolatileAPRPool() ;
+ LLScopedVolatileAPRPool pool;
+ s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
if (s != APR_SUCCESS)
{
@@ -683,49 +421,44 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname,
}
//static
-bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
+bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags)
{
- apr_file_t* apr_file;
+ apr_file_t* file_handle;
apr_status_t s;
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
- s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
+ LLScopedVolatileAPRPool pool;
+ s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
- if (s != APR_SUCCESS || !apr_file)
+ if (s != APR_SUCCESS || !file_handle)
{
- pool->clearVolatileAPRPool() ;
return false;
}
else
{
- apr_file_close(apr_file) ;
- pool->clearVolatileAPRPool() ;
+ apr_file_close(file_handle);
return true;
}
}
//static
-S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
+S32 LLAPRFile::size(const std::string& filename)
{
- apr_file_t* apr_file;
+ apr_file_t* file_handle;
apr_finfo_t info;
apr_status_t s;
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
- s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool());
+ LLScopedVolatileAPRPool pool;
+ s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
- if (s != APR_SUCCESS || !apr_file)
+ if (s != APR_SUCCESS || !file_handle)
{
- pool->clearVolatileAPRPool() ;
-
return 0;
}
else
{
- apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
+ apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, file_handle);
- apr_file_close(apr_file) ;
- pool->clearVolatileAPRPool() ;
+ apr_file_close(file_handle) ;
if (s == APR_SUCCESS)
{
@@ -739,31 +472,29 @@ S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
}
//static
-bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
+bool LLAPRFile::makeDir(const std::string& dirname)
{
apr_status_t s;
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
- s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool());
- pool->clearVolatileAPRPool() ;
+ LLScopedVolatileAPRPool pool;
+ s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
if (s != APR_SUCCESS)
{
ll_apr_warn_status(s);
- LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;
+ LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL;
return false;
}
return true;
}
//static
-bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
+bool LLAPRFile::removeDir(const std::string& dirname)
{
apr_status_t s;
- pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
- s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool());
- pool->clearVolatileAPRPool() ;
+ LLScopedVolatileAPRPool pool;
+ s = apr_file_remove(dirname.c_str(), pool);
if (s != APR_SUCCESS)
{
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index af33ce666f..3f846f1314 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -50,71 +50,9 @@
#include "apr_atomic.h"
#include "llstring.h"
-extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
-extern apr_thread_mutex_t* gCallStacksLogMutexp;
-
struct apr_dso_handle_t;
-
-/**
- * @brief initialize the common apr constructs -- apr itself, the
- * global pool, and a mutex.
- */
-void LL_COMMON_API ll_init_apr();
-
-/**
- * @brief Cleanup those common apr constructs.
- */
-void LL_COMMON_API ll_cleanup_apr();
-
-//
-//LL apr_pool
-//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
-//
-class LL_COMMON_API LLAPRPool
-{
-public:
- LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
- virtual ~LLAPRPool() ;
-
- virtual apr_pool_t* getAPRPool() ;
- apr_status_t getStatus() {return mStatus ; }
-
-protected:
- void releaseAPRPool() ;
- void createAPRPool() ;
-
-protected:
- apr_pool_t* mPool ; //pointing to an apr_pool
- apr_pool_t* mParent ; //parent pool
- apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work.
- apr_status_t mStatus ; //status when creating the pool
- BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true.
-};
-
-//
-//volatile LL apr_pool
-//which clears memory automatically.
-//so it can not hold static data or data after memory is cleared
-//
-class LL_COMMON_API LLVolatileAPRPool : public LLAPRPool
-{
-public:
- LLVolatileAPRPool(BOOL is_local = TRUE, apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
- virtual ~LLVolatileAPRPool();
-
- /*virtual*/ apr_pool_t* getAPRPool() ; //define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
- apr_pool_t* getVolatileAPRPool() ;
- void clearVolatileAPRPool() ;
-
- BOOL isFull() ;
-
-private:
- S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
- S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
-
- apr_thread_mutex_t *mMutexp;
- apr_pool_t *mMutexPool;
-} ;
+class LLAPRPool;
+class LLVolatileAPRPool;
/**
* @class LLScopedLock
@@ -205,15 +143,20 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
// make this non copyable since a copy closes the file
private:
apr_file_t* mFile ;
- LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.
+ LLVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use.
+ LLAPRPool* mRegularFilePoolp; // ...or a regular pool.
public:
+ enum access_t {
+ long_lived, // Use a global pool for long-lived file accesses.
+ short_lived // Use a volatile pool for short-lived file accesses.
+ };
+
LLAPRFile() ;
- LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL);
+ LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep = NULL, access_t access_type = short_lived);
~LLAPRFile() ;
-
- apr_status_t open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL, S32* sizep = NULL);
- apr_status_t open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool); //use gAPRPoolp.
+
+ apr_status_t open(const std::string& filename, apr_int32_t flags, access_t access_type, S32* sizep = NULL);
apr_status_t close() ;
// Returns actual offset, -1 if seek fails
@@ -226,32 +169,24 @@ public:
apr_file_t* getFileHandle() {return mFile;}
-private:
- apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;
-
//
//*******************************************************************************************************************************
//static components
//
-public:
- static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist.
-
private:
- static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags);
- static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ;
static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset);
public:
// returns false if failure:
- static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL);
- static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL);
- static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ);
- static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL);
- static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
- static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
+ static bool remove(const std::string& filename);
+ static bool rename(const std::string& filename, const std::string& newname);
+ static bool isExist(const std::string& filename, apr_int32_t flags = APR_READ);
+ static S32 size(const std::string& filename);
+ static bool makeDir(const std::string& dirname);
+ static bool removeDir(const std::string& dirname);
// Returns bytes read/written, 0 if read/write fails:
- static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
- static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append
+ static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes);
+ static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); // offset<0 means append
//*******************************************************************************************************************************
};
@@ -267,6 +202,4 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* han
void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
-extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
-
#endif // LL_LLAPR_H
diff --git a/indra/llcommon/llaprpool.cpp b/indra/llcommon/llaprpool.cpp
new file mode 100644
index 0000000000..6f21b61b65
--- /dev/null
+++ b/indra/llcommon/llaprpool.cpp
@@ -0,0 +1,202 @@
+/**
+ * @file llaprpool.cpp
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ *
+ * CHANGELOG
+ * and additional copyright holders.
+ *
+ * 04/04/2010
+ * - Initial version, written by Aleric Inglewood @ SL
+ *
+ * 10/11/2010
+ * - Added APR_HAS_THREADS #if's to allow creation and destruction
+ * of subpools by threads other than the parent pool owner.
+ */
+
+#include "linden_common.h"
+
+#include "llerror.h"
+#include "llaprpool.h"
+#include "llthread.h"
+
+// Create a subpool from parent.
+void LLAPRPool::create(LLAPRPool& parent)
+{
+ llassert(!mPool); // Must be non-initialized.
+ mParent = &parent;
+ if (!mParent) // Using the default parameter?
+ {
+ // By default use the root pool of the current thread.
+ mParent = &LLThreadLocalData::tldata().mRootPool;
+ }
+ llassert(mParent->mPool); // Parent must be initialized.
+#if APR_HAS_THREADS
+ // As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html):
+ //
+ // Note that most operations on pools are not thread-safe: a single pool should only be
+ // accessed by a single thread at any given time. The one exception to this rule is creating
+ // a subpool of a given pool: one or more threads can safely create subpools at the same
+ // time that another thread accesses the parent pool.
+ //
+ // In other words, it's safe for any thread to create a (sub)pool, independent of who
+ // owns the parent pool.
+ mOwner = apr_os_thread_current();
+#else
+ mOwner = mParent->mOwner;
+ llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+#endif
+ apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
+ llassert_always(apr_pool_create_status == APR_SUCCESS);
+ llassert(mPool); // Initialized.
+ apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
+}
+
+// Destroy the (sub)pool, if any.
+void LLAPRPool::destroy(void)
+{
+ // Only do anything if we are not already (being) destroyed.
+ if (mPool)
+ {
+#if !APR_HAS_THREADS
+ // If we are a root pool, then every thread may destruct us: in that case
+ // we have to assume that no other thread will use this pool concurrently,
+ // of course. Otherwise, if we are a subpool, only the thread that owns
+ // the parent may destruct us, since that is the pool that is still alive,
+ // possibly being used by others and being altered here.
+ llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current()));
+#endif
+ apr_pool_t* pool = mPool; // The use of apr_pool_t is OK here.
+ // Temporary store before destroying the pool.
+ mPool = NULL; // Mark that we are BEING destructed.
+ apr_pool_cleanup_kill(pool, this, &s_plain_cleanup);
+ apr_pool_destroy(pool);
+ }
+}
+
+bool LLAPRPool::parent_is_being_destructed(void)
+{
+ return mParent && (!mParent->mPool || mParent->parent_is_being_destructed());
+}
+
+LLAPRInitialization::LLAPRInitialization(void)
+{
+ static bool apr_initialized = false;
+
+ if (!apr_initialized)
+ {
+ apr_initialize();
+ }
+
+ apr_initialized = true;
+}
+
+bool LLAPRRootPool::sCountInitialized = false;
+apr_uint32_t volatile LLAPRRootPool::sCount;
+
+apr_thread_mutex_t* gLogMutexp;
+apr_thread_mutex_t* gCallStacksLogMutexp;
+
+LLAPRRootPool::LLAPRRootPool(void) : LLAPRInitialization(), LLAPRPool(0)
+{
+ // sCountInitialized don't need locking because when we get here there is still only a single thread.
+ if (!sCountInitialized)
+ {
+ // Initialize the logging mutex
+ apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
+ apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
+
+ apr_status_t status = apr_atomic_init(mPool);
+ llassert_always(status == APR_SUCCESS);
+ apr_atomic_set32(&sCount, 1); // Set to 1 to account for the global root pool.
+ sCountInitialized = true;
+
+ // Initialize thread-local APR pool support.
+ // Because this recursively calls LLAPRRootPool::LLAPRRootPool(void)
+ // it must be done last, so that sCount is already initialized.
+ LLThreadLocalData::init();
+ }
+ apr_atomic_inc32(&sCount);
+}
+
+LLAPRRootPool::~LLAPRRootPool()
+{
+ if (!apr_atomic_dec32(&sCount))
+ {
+ // The last pool was destructed. Cleanup remainder of APR.
+ LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
+
+ if (gLogMutexp)
+ {
+ // Clean up the logging mutex
+
+ // All other threads NEED to be done before we clean up APR, so this is okay.
+ apr_thread_mutex_destroy(gLogMutexp);
+ gLogMutexp = NULL;
+ }
+ if (gCallStacksLogMutexp)
+ {
+ // Clean up the logging mutex
+
+ // All other threads NEED to be done before we clean up APR, so this is okay.
+ apr_thread_mutex_destroy(gCallStacksLogMutexp);
+ gCallStacksLogMutexp = NULL;
+ }
+
+ // Must destroy ALL, and therefore this last LLAPRRootPool, before terminating APR.
+ static_cast<LLAPRRootPool*>(this)->destroy();
+
+ apr_terminate();
+ }
+}
+
+//static
+// Return a global root pool that is independent of LLThreadLocalData.
+// Normally you should NOT use this. Only use for early initialization
+// (before main) and deinitialization (after main).
+LLAPRRootPool& LLAPRRootPool::get(void)
+{
+ static LLAPRRootPool global_APRpool(0);
+ return global_APRpool;
+}
+
+void LLVolatileAPRPool::clearVolatileAPRPool()
+{
+ llassert_always(mNumActiveRef > 0);
+ if (--mNumActiveRef == 0)
+ {
+ if (isOld())
+ {
+ destroy();
+ mNumTotalRef = 0 ;
+ }
+ else
+ {
+ // This does not actually free the memory,
+ // it just allows the pool to re-use this memory for the next allocation.
+ clear();
+ }
+ }
+
+ // Paranoia check if the pool is jammed.
+ llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
+}
diff --git a/indra/llcommon/llaprpool.h b/indra/llcommon/llaprpool.h
new file mode 100644
index 0000000000..bf4102c584
--- /dev/null
+++ b/indra/llcommon/llaprpool.h
@@ -0,0 +1,256 @@
+/**
+ * @file llaprpool.h
+ * @brief Implementation of LLAPRPool
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ *
+ * CHANGELOG
+ * and additional copyright holders.
+ *
+ * 04/04/2010
+ * - Initial version, written by Aleric Inglewood @ SL
+ *
+ * 10/11/2010
+ * - Added APR_HAS_THREADS #if's to allow creation and destruction
+ * of subpools by threads other than the parent pool owner.
+ *
+ * 05/02/2011
+ * - Fixed compilation on windows: Suppress compile warning 4996
+ * and include <winsock2.h> before including <ws2tcpip.h>,
+ * by Merov Linden @ SL.
+ */
+
+#ifndef LL_LLAPRPOOL_H
+#define LL_LLAPRPOOL_H
+
+#ifdef LL_WINDOWS
+#pragma warning(push)
+#pragma warning(disable:4996)
+#include <winsock2.h>
+#include <ws2tcpip.h> // Needed before including apr_portable.h
+#pragma warning(pop)
+#endif
+
+#include "apr_portable.h"
+#include "apr_pools.h"
+#include "llerror.h"
+
+extern void ll_init_apr();
+
+/**
+ * @brief A wrapper around the APR memory pool API.
+ *
+ * Usage of this class should be restricted to passing it to libapr-1 function calls that need it.
+ *
+ */
+class LL_COMMON_API LLAPRPool
+{
+protected:
+ //! Pointer to the underlaying pool. NULL if not initialized.
+ apr_pool_t* mPool; // The use of apr_pool_t is OK here.
+ // This is the wrapped pointer that it is all about!
+ //! Pointer to the parent pool, if any. Only valid when mPool is non-zero.
+ LLAPRPool* mParent;
+ //! The thread that owns this memory pool. Only valid when mPool is non-zero.
+ apr_os_thread_t mOwner;
+
+public:
+ /// Construct an uninitialized (destructed) pool.
+ LLAPRPool(void) : mPool(NULL) { }
+
+ /// Construct a subpool from an existing pool.
+ /// This is not a copy-constructor, this class doesn't have one!
+ LLAPRPool(LLAPRPool& parent) : mPool(NULL) { create(parent); }
+
+ /// Destruct the memory pool (free all of its subpools and allocated memory).
+ ~LLAPRPool() { destroy(); }
+
+protected:
+ /// Create a pool that is allocated from the Operating System. Only used by LLAPRRootPool.
+ LLAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current())
+ {
+ apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL);
+ llassert_always(apr_pool_create_status == APR_SUCCESS);
+ llassert(mPool);
+ apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
+ }
+
+public:
+ /// Create a subpool from parent. May only be called for an uninitialized/destroyed pool.
+ /// The default parameter causes the root pool of the current thread to be used.
+ void create(LLAPRPool& parent = *static_cast<LLAPRPool*>(NULL));
+
+ /// Destroy the (sub)pool, if any.
+ void destroy(void);
+
+ // Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool.
+ typedef LLAPRPool* const LLAPRPool::* const bool_type;
+ /// Return true if the pool is initialized.
+ operator bool_type() const { return mPool ? &LLAPRPool::mParent : 0; }
+
+ /// Painful, but we have to either provide access to this, or wrap
+ /// every APR function call that needs an apr pool as argument.
+ /// NEVER destroy a pool that is returned by this function!
+ apr_pool_t* operator()(void) const // The use of apr_pool_t is OK here.
+ // This is the accessor for passing the pool to libapr-1 functions.
+ {
+ llassert(mPool);
+ llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ return mPool;
+ }
+
+ /// Free all memory without destructing the pool.
+ void clear(void)
+ {
+ llassert(mPool);
+ llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ apr_pool_clear(mPool);
+ }
+
+// These methods would make this class 'complete' (as wrapper around the libapr
+// pool functions), but we don't use memory pools in the viewer (only when
+// we are forced to pass one to a libapr call), so don't define them in order
+// not to encourage people to use them.
+#if 0
+ void* palloc(size_t size)
+ {
+ llassert(mPool);
+ llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ return apr_palloc(mPool, size);
+ }
+ void* pcalloc(size_t size)
+ {
+ llassert(mPool);
+ llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ return apr_pcalloc(mPool, size);
+ }
+#endif
+
+private:
+ bool parent_is_being_destructed(void);
+ static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<LLAPRPool*>(userdata)->plain_cleanup(); }
+
+ apr_status_t plain_cleanup(void)
+ {
+ if (mPool && // We are not being destructed,
+ parent_is_being_destructed()) // but our parent is.
+ // This means the pool is being destructed recursively by libapr
+ // because one of its parents is being destructed.
+ {
+ mPool = NULL; // Stop destroy() from destructing the pool again.
+ }
+ return APR_SUCCESS;
+ }
+};
+
+class LLAPRInitialization
+{
+public:
+ LLAPRInitialization(void);
+};
+
+/**
+ * @brief Root memory pool (allocates memory from the operating system).
+ *
+ * This class should only be used by LLThreadLocalData
+ * (and LLMutexRootPool when APR_HAS_THREADS isn't defined).
+ */
+class LL_COMMON_API LLAPRRootPool : public LLAPRInitialization, public LLAPRPool
+{
+private:
+ /// Construct a root memory pool. Should only be used by LLThreadLocalData and LLMutexRootPool.
+ friend class LLThreadLocalData;
+#if !APR_HAS_THREADS
+ friend class LLMutexRootPool;
+#endif
+ /// Construct a root memory pool.
+ /// Should only be used by LLThreadLocalData.
+ LLAPRRootPool(void);
+ ~LLAPRRootPool();
+
+private:
+ // Keep track of how many root pools exist and when the last one is destructed.
+ static bool sCountInitialized;
+ static apr_uint32_t volatile sCount;
+
+public:
+ // Return a global root pool that is independent of LLThreadLocalData.
+ // Normally you should not use this. Only use for early initialization
+ // (before main) and deinitialization (after main).
+ static LLAPRRootPool& get(void);
+
+#if APR_POOL_DEBUG
+ void grab_ownership(void)
+ {
+ // You need a patched libapr to use this.
+ // See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI
+ apr_pool_owner_set(mPool);
+ }
+#endif
+
+private:
+ // Used for constructing the Special Global Root Pool (returned by LLAPRRootPool::get).
+ // It is the same as the default constructor but omits to increment sCount. As a result,
+ // we must be sure that at least one other LLAPRRootPool is created before termination
+ // of the application (which is the case: we create one LLAPRRootPool per thread).
+ LLAPRRootPool(int) : LLAPRInitialization(), LLAPRPool(0) { }
+};
+
+/** Volatile memory pool
+ *
+ * 'Volatile' APR memory pool which normally only clears memory,
+ * and does not destroy the pool (the same pool is reused) for
+ * greater efficiency. However, as a safe guard the apr pool
+ * is destructed every FULL_VOLATILE_APR_POOL uses to allow
+ * the system memory to be allocated more efficiently and not
+ * get scattered through RAM.
+ */
+class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool
+{
+public:
+ LLVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { }
+
+ void clearVolatileAPRPool(void);
+
+ bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; }
+ bool isUnused() const { return mNumActiveRef == 0; }
+
+private:
+ friend class LLScopedVolatileAPRPool;
+ friend class LLAPRFile;
+ apr_pool_t* getVolatileAPRPool(void) // The use of apr_pool_t is OK here.
+ {
+ if (!mPool) create();
+ ++mNumActiveRef;
+ ++mNumTotalRef;
+ return LLAPRPool::operator()();
+ }
+
+private:
+ S32 mNumActiveRef; // Number of active uses of the pool.
+ S32 mNumTotalRef; // Number of total uses of the pool since last creation.
+
+ // Maximum number of references to LLVolatileAPRPool until the pool is recreated.
+ static S32 const FULL_VOLATILE_APR_POOL = 1024;
+};
+
+#endif // LL_LLAPRPOOL_H
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 8be9e4f4de..b8a7394852 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -31,17 +31,9 @@
#include "llthread.h"
//static
-BOOL LLCommon::sAprInitialized = FALSE;
-
-//static
void LLCommon::initClass()
{
LLMemory::initClass();
- if (!sAprInitialized)
- {
- ll_init_apr();
- sAprInitialized = TRUE;
- }
LLTimer::initClass();
LLThreadSafeRefCount::initThreadSafeRefCount();
// LLWorkerThread::initClass();
@@ -55,10 +47,5 @@ void LLCommon::cleanupClass()
// LLWorkerThread::cleanupClass();
LLThreadSafeRefCount::cleanupThreadSafeRefCount();
LLTimer::cleanupClass();
- if (sAprInitialized)
- {
- ll_cleanup_apr();
- sAprInitialized = FALSE;
- }
LLMemory::cleanupClass();
}
diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h
index ca9cad5d05..171590f3d8 100644
--- a/indra/llcommon/llcommon.h
+++ b/indra/llcommon/llcommon.h
@@ -35,8 +35,6 @@ class LL_COMMON_API LLCommon
public:
static void initClass();
static void cleanupClass();
-private:
- static BOOL sAprInitialized;
};
#endif
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index bb64152407..75048073ca 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -866,6 +866,9 @@ You get:
*/
+extern apr_thread_mutex_t* gLogMutexp;
+extern apr_thread_mutex_t* gCallStacksLogMutexp;
+
namespace {
bool checkLevelMap(const LevelMap& map, const std::string& key,
LLError::ELevel& level)
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 4a42241c4f..15d167c32e 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -296,5 +296,4 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
Such computation is done iff the message will be logged.
*/
-
#endif // LL_LLERROR_H
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index d394f179fb..4b5cdbe288 100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
@@ -30,8 +30,7 @@
LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
: LLLineBuffer(),
- mMaxLines(max_lines),
- mMutex(NULL)
+ mMaxLines(max_lines)
{
mTimer.reset();
}
diff --git a/indra/llcommon/llscopedvolatileaprpool.h b/indra/llcommon/llscopedvolatileaprpool.h
new file mode 100644
index 0000000000..dbaf4edcad
--- /dev/null
+++ b/indra/llcommon/llscopedvolatileaprpool.h
@@ -0,0 +1,52 @@
+/**
+ * @file llscopedvolatileaprpool.h
+ * @brief Implementation of LLScopedVolatileAPRPool
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSCOPEDVOLATILEAPRPOOL_H
+#define LL_LLSCOPEDVOLATILEAPRPOOL_H
+
+#include "llthread.h"
+
+/** Scoped volatile memory pool.
+ *
+ * As the LLVolatileAPRPool should never keep allocations very
+ * long, its most common use is for allocations with a lifetime
+ * equal to it's scope.
+ *
+ * This is a convenience class that makes just a little easier to type.
+ */
+class LL_COMMON_API LLScopedVolatileAPRPool
+{
+private:
+ LLVolatileAPRPool& mPool;
+ apr_pool_t* mScopedAPRpool; // The use of apr_pool_t is OK here.
+public:
+ LLScopedVolatileAPRPool() : mPool(LLThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { }
+ ~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); }
+ //! @attention Only use this to pass the underlaying pointer to a libapr-1 function that requires it.
+ operator apr_pool_t*() const { return mScopedAPRpool; } // The use of apr_pool_t is OK here.
+};
+
+#endif
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 49d05ef411..4917e3b935 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -63,6 +63,9 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
{
LLThread *threadp = (LLThread *)datap;
+ // Create a thread local data.
+ LLThreadLocalData::create(threadp);
+
// Run the user supplied function
threadp->run();
@@ -75,38 +78,20 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
}
-LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
- mPaused(FALSE),
+LLThread::LLThread(std::string const& name) :
+ mPaused(false),
mName(name),
mAPRThreadp(NULL),
- mStatus(STOPPED)
+ mStatus(STOPPED),
+ mThreadLocalData(NULL)
{
- // 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);
-
- mLocalAPRFilePoolp = NULL ;
+ mRunCondition = new LLCondition;
}
LLThread::~LLThread()
{
shutdown();
-
- if(mLocalAPRFilePoolp)
- {
- delete mLocalAPRFilePoolp ;
- mLocalAPRFilePoolp = NULL ;
- }
}
void LLThread::shutdown()
@@ -143,7 +128,7 @@ void LLThread::shutdown()
if (!isStopped())
{
// This thread just wouldn't stop, even though we gave it time
- llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
+ llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl;
// Put a stake in its heart.
apr_thread_exit(mAPRThreadp, -1);
return;
@@ -153,15 +138,8 @@ void LLThread::shutdown()
delete mRunCondition;
mRunCondition = 0;
-
- if (mIsLocalPool && mAPRPoolp)
- {
- apr_pool_destroy(mAPRPoolp);
- mAPRPoolp = 0;
- }
}
-
void LLThread::start()
{
llassert(isStopped());
@@ -170,7 +148,7 @@ void LLThread::start()
mStatus = RUNNING;
apr_status_t status =
- apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
+ apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
if(status == APR_SUCCESS)
{
@@ -195,7 +173,7 @@ void LLThread::pause()
if (!mPaused)
{
// this will cause the thread to stop execution as soon as checkPause() is called
- mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread
+ mPaused = true; // Does not need to be atomic since this is only set/unset from the main thread
}
}
@@ -203,7 +181,7 @@ void LLThread::unpause()
{
if (mPaused)
{
- mPaused = 0;
+ mPaused = false;
}
wake(); // wake up the thread if necessary
@@ -280,85 +258,76 @@ void LLThread::wakeLocked()
}
}
-//============================================================================
-
-LLMutex::LLMutex(apr_pool_t *poolp) :
- mAPRMutexp(NULL)
-{
- //if (poolp)
- //{
- // mIsLocalPool = FALSE;
- // mAPRPoolp = poolp;
- //}
- //else
- {
- mIsLocalPool = TRUE;
- apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
- }
- apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
-}
+#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;
-LLMutex::~LLMutex()
+//static
+void LLThreadLocalData::init(void)
{
-#if MUTEX_DEBUG
- llassert_always(!isLocked()); // better not be locked!
-#endif
- apr_thread_mutex_destroy(mAPRMutexp);
- mAPRMutexp = NULL;
- if (mIsLocalPool)
+ // Only do this once.
+ if (sThreadLocalDataKey)
{
- apr_pool_destroy(mAPRPoolp);
+ return;
}
-}
+ 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.
-void LLMutex::lock()
-{
- 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;
+ // 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();
#endif
}
-void LLMutex::unlock()
+// This is called once for every thread when the thread is destructed.
+//static
+void LLThreadLocalData::destroy(void* thread_local_data)
{
-#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);
+ delete static_cast<LLThreadLocalData*>(thread_local_data);
}
-bool LLMutex::isLocked()
+//static
+void LLThreadLocalData::create(LLThread* threadp)
{
- apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
- if (APR_STATUS_IS_EBUSY(status))
+ LLThreadLocalData* new_tld = new LLThreadLocalData;
+ if (threadp)
{
- return true;
+ threadp->mThreadLocalData = new_tld;
}
- else
+ apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey);
+ llassert_always(status == APR_SUCCESS);
+}
+
+//static
+LLThreadLocalData& LLThreadLocalData::tldata(void)
+{
+ if (!sThreadLocalDataKey)
{
- apr_thread_mutex_unlock(mAPRMutexp);
- return false;
+ LLThreadLocalData::init();
}
+
+ void* data;
+ apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
+ llassert_always(status == APR_SUCCESS);
+ return *static_cast<LLThreadLocalData*>(data);
}
//============================================================================
-LLCondition::LLCondition(apr_pool_t *poolp) :
- LLMutex(poolp)
+LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent)
{
- // base class (LLMutex) has already ensured that mAPRPoolp is set up.
-
- apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
+ apr_thread_cond_create(&mAPRCondp, mPool());
}
@@ -396,7 +365,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
{
if (!sMutex)
{
- sMutex = new LLMutex(0);
+ sMutex = new LLMutex;
}
}
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index f1c6cd75af..757832b8ca 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -29,12 +29,34 @@
#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;
class LLCondition;
+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
{
public:
@@ -45,7 +67,7 @@ public:
QUITTING= 2 // Someone wants this thread to quit
} EThreadStatus;
- LLThread(const std::string& name, apr_pool_t *poolp = NULL);
+ LLThread(std::string const& name);
virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
virtual void shutdown(); // stops the thread
@@ -60,7 +82,7 @@ public:
// Called from MAIN THREAD.
void pause();
void unpause();
- bool isPaused() { return isStopped() || mPaused == TRUE; }
+ bool isPaused() { return isStopped() || mPaused; }
// Cause the thread to wake up and check its condition
void wake();
@@ -74,11 +96,11 @@ public:
// this kicks off the apr thread
void start(void);
- apr_pool_t *getAPRPool() { return mAPRPoolp; }
- LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
+ // Return thread-local data for the current thread.
+ static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
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);
@@ -88,14 +110,10 @@ protected:
LLCondition* mRunCondition;
apr_thread_t *mAPRThreadp;
- apr_pool_t *mAPRPoolp;
- BOOL mIsLocalPool;
EThreadStatus mStatus;
- //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 ;
+ friend void LLThreadLocalData::create(LLThread* threadp);
+ LLThreadLocalData* mThreadLocalData;
void setQuitting();
@@ -125,30 +143,80 @@ protected:
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
-class LL_COMMON_API LLMutex
+#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
{
public:
- 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
-
+ void lock() { apr_thread_mutex_lock(mAPRMutexp); }
+ void unlock() { apr_thread_mutex_unlock(mAPRMutexp); }
+ // 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; }
+
+protected:
+ // mAPRMutexp is initialized and uninitialized in the derived class.
+ apr_thread_mutex_t* mAPRMutexp;
+};
+
+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()
+ {
+ llassert(!isLocked()); // better not be locked!
+ apr_thread_mutex_destroy(mAPRMutexp);
+ mAPRMutexp = NULL;
+ }
+
protected:
- apr_thread_mutex_t *mAPRMutexp;
- apr_pool_t *mAPRPoolp;
- BOOL mIsLocalPool;
-#if MUTEX_DEBUG
- std::map<U32, BOOL> mIsLocked;
+ 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();
#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(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
+ LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool);
~LLCondition();
void wait(); // blocks
@@ -159,10 +227,10 @@ protected:
apr_thread_cond_t *mAPRCondp;
};
-class LLMutexLock
+class LL_COMMON_API LLMutexLock
{
public:
- LLMutexLock(LLMutex* mutex)
+ LLMutexLock(LLMutexBase* mutex)
{
mMutex = mutex;
mMutex->lock();
@@ -172,7 +240,7 @@ public:
mMutex->unlock();
}
private:
- LLMutex* mMutex;
+ LLMutexBase* mMutex;
};
//============================================================================
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index 8a73e632a9..05d24944f3 100644
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -34,19 +34,11 @@
//-----------------------------------------------------------------------------
-LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
- mOwnsPool(pool == 0),
- mPool(pool),
+LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(unsigned int capacity):
mQueue(0)
{
- if(mOwnsPool) {
- apr_status_t status = apr_pool_create(&mPool, 0);
- if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool");
- } else {
- ; // No op.
- }
-
- apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
+ mPool.create();
+ apr_status_t status = apr_queue_create(&mQueue, capacity, mPool());
if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
}
@@ -59,7 +51,6 @@ LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
" elements;" << "memory will be leaked" << LL_ENDL;
apr_queue_term(mQueue);
}
- if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
}
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 58cac38769..43d0b396f2 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -30,9 +30,9 @@
#include <string>
#include <stdexcept>
+#include "llaprpool.h"
-struct apr_pool_t; // From apr_pools.h
class LLThreadSafeQueueImplementation; // See below.
@@ -75,7 +75,7 @@ struct apr_queue_t; // From apr_queue.h
class LL_COMMON_API LLThreadSafeQueueImplementation
{
public:
- LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
+ LLThreadSafeQueueImplementation(unsigned int capacity);
~LLThreadSafeQueueImplementation();
void pushFront(void * element);
bool tryPushFront(void * element);
@@ -84,8 +84,7 @@ public:
size_t size();
private:
- bool mOwnsPool;
- apr_pool_t * mPool;
+ LLAPRPool mPool; // The pool used for mQueue.
apr_queue_t * mQueue;
};
@@ -99,9 +98,8 @@ class LLThreadSafeQueue
public:
typedef ElementT value_type;
- // If the pool is set to NULL one will be allocated and managed by this
- // queue.
- LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
+ // Constructor.
+ LLThreadSafeQueue(unsigned int capacity = 1024);
// Add an element to the front of queue (will block if the queue has
// reached capacity).
@@ -139,8 +137,8 @@ private:
template<typename ElementT>
-LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
- mImplementation(pool, capacity)
+LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(unsigned int capacity) :
+ mImplementation(capacity)
{
; // No op.
}
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 3ac50832fd..6b308bb917 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -37,12 +37,7 @@
LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) :
LLQueuedThread(name, threaded)
{
- mDeleteMutex = new LLMutex(NULL);
-
- if(!mLocalAPRFilePoolp)
- {
- mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
- }
+ mDeleteMutex = new LLMutex;
}
LLWorkerThread::~LLWorkerThread()
@@ -204,7 +199,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
mWorkerClassName(name),
mRequestHandle(LLWorkerThread::nullHandle()),
mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
- mMutex(NULL),
mWorkFlags(0)
{
if (!mWorkerThread)
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 9bff18303e..bef5ef53fe 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -94,7 +94,6 @@ public:
private:
void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
-
};
//============================================================================
@@ -194,7 +193,7 @@ protected:
U32 mRequestPriority; // last priority set
private:
- LLMutex mMutex;
+ LLMutexRootPool mMutex; // Use LLMutexRootPool since this object is created and destructed by multiple threads.
LLAtomicU32 mWorkFlags;
};
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 68e45f36e4..8f7916f565 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -390,8 +390,7 @@ bool LLCrashLogger::init()
return false;
}
- gServicePump = new LLPumpIO(gAPRPoolp);
- gServicePump->prime(gAPRPoolp);
+ gServicePump = new LLPumpIO;
LLHTTPClient::setPump(*gServicePump);
//If we've opened the crash logger, assume we can delete the marker file if it exists
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 39211bf7fa..f4399d4ed4 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -51,7 +51,7 @@ LLMutex* LLImage::sMutex = NULL;
//static
void LLImage::initClass()
{
- sMutex = new LLMutex(NULL);
+ sMutex = new LLMutex;
}
//static
@@ -1557,8 +1557,7 @@ BOOL LLImageFormatted::load(const std::string &filename)
resetLastError();
S32 file_size = 0;
- LLAPRFile infile ;
- infile.open(filename, LL_APR_RB, NULL, &file_size);
+ LLAPRFile infile(filename, LL_APR_RB, &file_size);
apr_file_t* apr_file = infile.getFileHandle();
if (!apr_file)
{
@@ -1593,8 +1592,7 @@ BOOL LLImageFormatted::save(const std::string &filename)
{
resetLastError();
- LLAPRFile outfile ;
- outfile.open(filename, LL_APR_WB);
+ LLAPRFile outfile(filename, LL_APR_WB);
if (!outfile.getFileHandle())
{
setLastError("Unable to open file for writing", filename);
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index 835664c60f..8a10956a5b 100644
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -40,7 +40,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
mSrcFilename = src_filename;
S32 file_size = 0;
- apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size);
+ apr_status_t s = mInfile.open(src_filename, LL_APR_RB, LLAPRFile::long_lived, &file_size);
if (s != APR_SUCCESS)
{
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index cb2a85fa91..5f488a6764 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -358,8 +358,7 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
resetLastError();
S32 file_size = 0;
- LLAPRFile infile ;
- infile.open(filename, LL_APR_RB, NULL, &file_size);
+ LLAPRFile infile(filename, LL_APR_RB, &file_size);
apr_file_t* apr_file = infile.getFileHandle() ;
if (!apr_file)
{
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 28dc3bd313..2c6d6f31ea 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -35,20 +35,18 @@
LLImageDecodeThread::LLImageDecodeThread(bool threaded)
: LLQueuedThread("imagedecode", threaded)
{
- mCreationMutex = new LLMutex(getAPRPool());
}
//virtual
LLImageDecodeThread::~LLImageDecodeThread()
{
- delete mCreationMutex ;
}
// MAIN THREAD
// virtual
S32 LLImageDecodeThread::update(U32 max_time_ms)
{
- LLMutexLock lock(mCreationMutex);
+ LLMutexLock lock(&mCreationMutex);
for (creation_list_t::iterator iter = mCreationList.begin();
iter != mCreationList.end(); ++iter)
{
@@ -71,7 +69,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms)
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
{
- LLMutexLock lock(mCreationMutex);
+ LLMutexLock lock(&mCreationMutex);
handle_t handle = generateHandle();
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
return handle;
@@ -81,7 +79,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted*
// Returns the size of the mutex guarded list as an indication of sanity
S32 LLImageDecodeThread::tut_size()
{
- LLMutexLock lock(mCreationMutex);
+ LLMutexLock lock(&mCreationMutex);
S32 res = mCreationList.size();
return res;
}
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index c684222fa5..6a24b7522a 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -98,7 +98,7 @@ private:
};
typedef std::list<creation_info> creation_list_t;
creation_list_t mCreationList;
- LLMutex* mCreationMutex;
+ LLMutex mCreationMutex;
};
#endif
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index 88c195936c..734440d312 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -49,7 +49,7 @@ LLVolumeMgr::LLVolumeMgr()
{
// the LLMutex magic interferes with easy unit testing,
// so you now must manually call useMutex() to use it
- //mDataMutex = new LLMutex(gAPRPoolp);
+ //mDataMutex = new LLMutex;
}
LLVolumeMgr::~LLVolumeMgr()
@@ -216,7 +216,7 @@ void LLVolumeMgr::useMutex()
{
if (!mDataMutex)
{
- mDataMutex = new LLMutex(gAPRPoolp);
+ mDataMutex = new LLMutex;
}
}
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index 5a67035ed1..fab9858b69 100644
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llares.h"
+#include "llscopedvolatileaprpool.h"
#include <ares_dns.h>
#include <ares_version.h>
@@ -464,11 +465,6 @@ void LLAres::search(const std::string &query, LLResType type,
bool LLAres::process(U64 timeout)
{
- if (!gAPRPoolp)
- {
- ll_init_apr();
- }
-
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
apr_int32_t nsds = 0;
@@ -482,10 +478,7 @@ bool LLAres::process(U64 timeout)
return nsds > 0;
}
- apr_status_t status;
- LLAPRPool pool;
- status = pool.getStatus() ;
- ll_apr_assert_status(status);
+ LLScopedVolatileAPRPool scoped_pool;
for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
{
@@ -502,7 +495,7 @@ bool LLAres::process(U64 timeout)
apr_socket_t *aprSock = NULL;
- status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
+ apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
if (status != APR_SUCCESS)
{
ll_apr_warn_status(status);
@@ -511,7 +504,7 @@ bool LLAres::process(U64 timeout)
aprFds[nactive].desc.s = aprSock;
aprFds[nactive].desc_type = APR_POLL_SOCKET;
- aprFds[nactive].p = pool.getAPRPool();
+ aprFds[nactive].p = scoped_pool;
aprFds[nactive].rtnevents = 0;
aprFds[nactive].client_data = &socks[i];
@@ -520,7 +513,7 @@ bool LLAres::process(U64 timeout)
if (nactive > 0)
{
- status = apr_poll(aprFds, nactive, &nsds, timeout);
+ apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
if (status != APR_SUCCESS && status != APR_TIMEUP)
{
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index a485fa0160..4d3b382f7a 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -1039,7 +1039,7 @@ void LLCurl::initClass()
S32 mutex_count = CRYPTO_num_locks();
for (S32 i=0; i<mutex_count; i++)
{
- sSSLMutex.push_back(new LLMutex(NULL));
+ sSSLMutex.push_back(new LLMutex);
}
CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 3b18a9177c..d441492cf2 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -954,13 +954,9 @@ private:
// static
-LLHTTPNode& LLIOHTTPServer::create(
- apr_pool_t* pool, LLPumpIO& pump, U16 port)
+LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
{
- LLSocket::ptr_t socket = LLSocket::create(
- pool,
- LLSocket::STREAM_TCP,
- port);
+ LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port);
if(!socket)
{
llerrs << "Unable to initialize socket" << llendl;
@@ -969,7 +965,7 @@ LLHTTPNode& LLIOHTTPServer::create(
LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;
boost::shared_ptr<LLChainIOFactory> factory_ptr(factory);
- LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr);
+ LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr);
LLPumpIO::chain_t chain;
chain.push_back(LLIOPipe::ptr_t(server));
diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h
index 5c1b0531ff..2294e4b8ae 100644
--- a/indra/llmessage/lliohttpserver.h
+++ b/indra/llmessage/lliohttpserver.h
@@ -50,7 +50,7 @@ class LLIOHTTPServer
public:
typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);
- static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port);
+ static LLHTTPNode& create(LLPumpIO& pump, U16 port);
/**< Creates an HTTP wire server on the pump for the given TCP port.
*
* Returns the root node of the new server. Add LLHTTPNode instances
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index ca84fa8bb8..e802d9b3a6 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -35,6 +35,7 @@
#include "llhost.h"
#include "llmemtype.h"
#include "llpumpio.h"
+#include "llthread.h"
//
// constants
@@ -98,51 +99,31 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
///
// static
-LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
+LLSocket::ptr_t LLSocket::create(EType type, U16 port)
{
LLMemType m1(LLMemType::MTYPE_IO_TCP);
- LLSocket::ptr_t rv;
- apr_socket_t* socket = NULL;
- apr_pool_t* new_pool = NULL;
apr_status_t status = APR_EGENERAL;
-
- // create a pool for the socket
- status = apr_pool_create(&new_pool, pool);
- if(ll_apr_warn_status(status))
- {
- if(new_pool) apr_pool_destroy(new_pool);
- return rv;
- }
+ LLSocket::ptr_t rv(new LLSocket);
if(STREAM_TCP == type)
{
- status = apr_socket_create(
- &socket,
- APR_INET,
- SOCK_STREAM,
- APR_PROTO_TCP,
- new_pool);
+ status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool());
}
else if(DATAGRAM_UDP == type)
{
- status = apr_socket_create(
- &socket,
- APR_INET,
- SOCK_DGRAM,
- APR_PROTO_UDP,
- new_pool);
+ status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool());
}
else
{
- if(new_pool) apr_pool_destroy(new_pool);
+ rv.reset();
return rv;
}
if(ll_apr_warn_status(status))
{
- if(new_pool) apr_pool_destroy(new_pool);
+ rv->mSocket = NULL;
+ rv.reset();
return rv;
}
- rv = ptr_t(new LLSocket(socket, new_pool));
if(port > 0)
{
apr_sockaddr_t* sa = NULL;
@@ -152,7 +133,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
APR_UNSPEC,
port,
0,
- new_pool);
+ rv->mPool());
if(ll_apr_warn_status(status))
{
rv.reset();
@@ -160,8 +141,8 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
}
// This allows us to reuse the address on quick down/up. This
// is unlikely to create problems.
- ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1));
- status = apr_socket_bind(socket, sa);
+ ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1));
+ status = apr_socket_bind(rv->mSocket, sa);
if(ll_apr_warn_status(status))
{
rv.reset();
@@ -175,7 +156,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
// to keep a queue of incoming connections for ACCEPT.
lldebugs << "Setting listen state for socket." << llendl;
status = apr_socket_listen(
- socket,
+ rv->mSocket,
LL_DEFAULT_LISTEN_BACKLOG);
if(ll_apr_warn_status(status))
{
@@ -196,21 +177,28 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
}
// static
-LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)
+LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
{
LLMemType m1(LLMemType::MTYPE_IO_TCP);
- LLSocket::ptr_t rv;
- if(!socket)
+ if (!listen_socket->getSocket())
+ {
+ status = APR_ENOSOCKET;
+ return LLSocket::ptr_t();
+ }
+ LLSocket::ptr_t rv(new LLSocket);
+ lldebugs << "accepting socket" << llendl;
+ status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool());
+ if (status != APR_SUCCESS)
{
+ rv->mSocket = NULL;
+ rv.reset();
return rv;
}
- rv = ptr_t(new LLSocket(socket, pool));
rv->mPort = PORT_EPHEMERAL;
rv->setOptions();
return rv;
}
-
bool LLSocket::blockingConnect(const LLHost& host)
{
if(!mSocket) return false;
@@ -223,7 +211,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
APR_UNSPEC,
host.getPort(),
0,
- mPool)))
+ mPool())))
{
return false;
}
@@ -234,13 +222,11 @@ bool LLSocket::blockingConnect(const LLHost& host)
return true;
}
-LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) :
- mSocket(socket),
- mPool(pool),
+LLSocket::LLSocket() :
+ mSocket(NULL),
+ mPool(LLThread::tldata().mRootPool),
mPort(PORT_INVALID)
{
- ll_debug_socket("Constructing wholely formed socket", mSocket);
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
}
LLSocket::~LLSocket()
@@ -252,10 +238,6 @@ LLSocket::~LLSocket()
ll_debug_socket("Destroying socket", mSocket);
apr_socket_close(mSocket);
}
- if(mPool)
- {
- apr_pool_destroy(mPool);
- }
}
void LLSocket::setOptions()
@@ -516,10 +498,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
///
LLIOServerSocket::LLIOServerSocket(
- apr_pool_t* pool,
LLIOServerSocket::socket_t listener,
factory_t factory) :
- mPool(pool),
mListenSocket(listener),
mReactor(factory),
mInitialized(false),
@@ -579,21 +559,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
lldebugs << "accepting socket" << llendl;
PUMP_DEBUG;
- apr_pool_t* new_pool = NULL;
- apr_status_t status = apr_pool_create(&new_pool, mPool);
- apr_socket_t* socket = NULL;
- status = apr_socket_accept(
- &socket,
- mListenSocket->getSocket(),
- new_pool);
- LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool));
+ apr_status_t status;
+ LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket));
//EStatus rv = STATUS_ERROR;
- if(llsocket)
+ if(llsocket && status == APR_SUCCESS)
{
PUMP_DEBUG;
apr_sockaddr_t* remote_addr;
- apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);
+ apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket());
char* remote_host_string;
apr_sockaddr_ip_get(&remote_host_string, remote_addr);
@@ -608,7 +582,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
{
chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
pump->addChain(chain, mResponseTimeout);
- status = STATUS_OK;
}
else
{
@@ -617,7 +590,8 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
}
else
{
- llwarns << "Unable to create linden socket." << llendl;
+ char buf[256];
+ llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl;
}
PUMP_DEBUG;
@@ -630,11 +604,10 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
#if 0
LLIODataSocket::LLIODataSocket(
U16 suggested_port,
- U16 start_discovery_port,
- apr_pool_t* pool) :
+ U16 start_discovery_port) :
mSocket(NULL)
{
- if(!pool || (PORT_INVALID == suggested_port)) return;
+ if(PORT_INVALID == suggested_port) return;
if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return;
apr_sockaddr_t* sa = NULL;
if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return;
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index 6806e5084a..1e35225512 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -38,7 +38,6 @@
*/
#include "lliopipe.h"
-#include "apr_pools.h"
#include "apr_network_io.h"
#include "llchainio.h"
@@ -88,34 +87,22 @@ public:
* socket. If you intend the socket to be known to external
* clients without prior port notification, do not use
* PORT_EPHEMERAL.
- * @param pool The apr pool to use. A child pool will be created
- * and associated with the socket.
* @param type The type of socket to create
* @param port The port for the socket
* @return A valid socket shared pointer if the call worked.
*/
static ptr_t create(
- apr_pool_t* pool,
EType type,
U16 port = PORT_EPHEMERAL);
/**
- * @brief Create a LLSocket when you already have an apr socket.
+ * @brief Create a LLSocket by accepting a connection from a listen socket.
*
- * This method assumes an ephemeral port. This is typically used
- * by calls which spawn a socket such as a call to
- * <code>accept()</code> as in the server socket. This call should
- * not fail if you have a valid apr socket.
- * Because of the nature of how accept() works, you are expected
- * to create a new pool for the socket, use that pool for the
- * accept, and pass it in here where it will be bound with the
- * socket and destroyed at the same time.
- * @param socket The apr socket to use
- * @param pool The pool used to create the socket. *NOTE: The pool
- * passed in will be DESTROYED.
+ * @param status Output. Status of the accept if a valid listen socket was passed.
+ * @param listen_socket The listen socket to use.
* @return A valid socket shared pointer if the call worked.
*/
- static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
+ static ptr_t create(apr_status_t& status, ptr_t& listen_socket);
/**
* @brief Perform a blocking connect to a host. Do not use in production.
@@ -150,7 +137,7 @@ protected:
* @brief Protected constructor since should only make sockets
* with one of the two <code>create()</code> calls.
*/
- LLSocket(apr_socket_t* socket, apr_pool_t* pool);
+ LLSocket(void);
/**
* @brief Set default socket options.
@@ -167,8 +154,8 @@ protected:
// The apr socket.
apr_socket_t* mSocket;
- // our memory pool
- apr_pool_t* mPool;
+ // Our memory pool.
+ LLAPRPool mPool;
// The port if we know it.
U16 mPort;
@@ -293,7 +280,7 @@ class LLIOServerSocket : public LLIOPipe
public:
typedef LLSocket::ptr_t socket_t;
typedef boost::shared_ptr<LLChainIOFactory> factory_t;
- LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);
+ LLIOServerSocket(socket_t listener, factory_t reactor);
virtual ~LLIOServerSocket();
/**
@@ -325,7 +312,6 @@ protected:
//@}
protected:
- apr_pool_t* mPool;
socket_t mListenSocket;
factory_t mReactor;
bool mInitialized;
@@ -359,8 +345,7 @@ public:
*/
LLIODataSocket(
U16 suggested_port,
- U16 start_discovery_port,
- apr_pool_t* pool);
+ U16 start_discovery_port);
virtual ~LLIODataSocket();
protected:
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 08b31e9c7a..8a898ab1b0 100644
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -50,6 +50,7 @@
#include "llstring.h"
#include "lluuid.h"
#include "net.h"
+#include "llaprpool.h"
//
// constants
@@ -57,7 +58,7 @@
const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
static bool gMailEnabled = true;
-static apr_pool_t* gMailPool;
+static LLAPRPool gMailPool;
static apr_sockaddr_t* gSockAddr;
static apr_socket_t* gMailSocket;
@@ -82,7 +83,7 @@ bool connect_smtp()
gSockAddr->sa.sin.sin_family,
SOCK_STREAM,
APR_PROTO_TCP,
- gMailPool);
+ gMailPool());
if(ll_apr_warn_status(status)) return false;
status = apr_socket_connect(gMailSocket, gSockAddr);
if(ll_apr_warn_status(status))
@@ -139,19 +140,19 @@ BOOL LLMail::send(
}
// static
-void LLMail::init(const std::string& hostname, apr_pool_t* pool)
+void LLMail::init(const std::string& hostname)
{
gMailSocket = NULL;
- if(hostname.empty() || !pool)
+ if (hostname.empty())
{
- gMailPool = NULL;
gSockAddr = NULL;
+ gMailPool.destroy();
}
else
{
- gMailPool = pool;
+ gMailPool.create();
- // collect all the information into a socaddr sturcture. the
+ // Collect all the information into a sockaddr structure. the
// documentation is a bit unclear, but I either have to
// specify APR_UNSPEC or not specify any flags. I am not sure
// which option is better.
@@ -161,7 +162,7 @@ void LLMail::init(const std::string& hostname, apr_pool_t* pool)
APR_UNSPEC,
25,
APR_IPV4_ADDR_OK,
- gMailPool);
+ gMailPool());
ll_apr_warn_status(status);
}
}
diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h
index 3791714363..0a5c532088 100644
--- a/indra/llmessage/llmail.h
+++ b/indra/llmessage/llmail.h
@@ -27,15 +27,13 @@
#ifndef LL_LLMAIL_H
#define LL_LLMAIL_H
-typedef struct apr_pool_t apr_pool_t;
-
#include "llsd.h"
class LLMail
{
public:
// if hostname is NULL, then the host is resolved as 'mail'
- static void init(const std::string& hostname, apr_pool_t* pool);
+ static void init(const std::string& hostname);
// Allow all email transmission to be disabled/enabled.
static void enable(bool mail_enabled);
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a8d2a0a224..89cfd66e1b 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -37,6 +37,7 @@
#include "llmemtype.h"
#include "llstl.h"
#include "llstat.h"
+#include "llthread.h"
// These should not be enabled in production, but they can be
// intensely useful during development for finding certain kinds of
@@ -162,14 +163,12 @@ struct ll_delete_apr_pollset_fd_client_data
/**
* LLPumpIO
*/
-LLPumpIO::LLPumpIO(apr_pool_t* pool) :
+LLPumpIO::LLPumpIO(void) :
mState(LLPumpIO::NORMAL),
mRebuildPollset(false),
mPollset(NULL),
mPollsetClientID(0),
mNextLock(0),
- mPool(NULL),
- mCurrentPool(NULL),
mCurrentPoolReallocCount(0),
mChainsMutex(NULL),
mCallbackMutex(NULL),
@@ -178,21 +177,24 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
mCurrentChain = mRunningChains.end();
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- initialize(pool);
+ initialize();
}
LLPumpIO::~LLPumpIO()
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- cleanup();
-}
-
-bool LLPumpIO::prime(apr_pool_t* pool)
-{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- cleanup();
- initialize(pool);
- return ((pool == NULL) ? false : true);
+#if LL_THREADS_APR
+ if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
+ if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
+#endif
+ mChainsMutex = NULL;
+ mCallbackMutex = NULL;
+ if(mPollset)
+ {
+// lldebugs << "cleaning up pollset" << llendl;
+ apr_pollset_destroy(mPollset);
+ mPollset = NULL;
+ }
}
bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
@@ -352,8 +354,7 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
{
// each fd needs a pool to work with, so if one was
// not specified, use this pool.
- // *FIX: Should it always be this pool?
- value.second.p = mPool;
+ value.second.p = (*mCurrentChain).mDescriptorsPool->operator()();
}
value.second.client_data = new S32(++mPollsetClientID);
(*mCurrentChain).mDescriptors.push_back(value);
@@ -825,39 +826,15 @@ void LLPumpIO::control(LLPumpIO::EControl op)
}
}
-void LLPumpIO::initialize(apr_pool_t* pool)
+void LLPumpIO::initialize(void)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- if(!pool) return;
+ mPool.create();
#if LL_THREADS_APR
// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
- apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
- apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-#endif
- mPool = pool;
-}
-
-void LLPumpIO::cleanup()
-{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-#if LL_THREADS_APR
- if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
- if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
+ apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
+ apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
#endif
- mChainsMutex = NULL;
- mCallbackMutex = NULL;
- if(mPollset)
- {
-// lldebugs << "cleaning up pollset" << llendl;
- apr_pollset_destroy(mPollset);
- mPollset = NULL;
- }
- if(mCurrentPool)
- {
- apr_pool_destroy(mCurrentPool);
- mCurrentPool = NULL;
- }
- mPool = NULL;
}
void LLPumpIO::rebuildPollset()
@@ -885,21 +862,19 @@ void LLPumpIO::rebuildPollset()
if(mCurrentPool
&& (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
{
- apr_pool_destroy(mCurrentPool);
- mCurrentPool = NULL;
+ mCurrentPool.destroy();
mCurrentPoolReallocCount = 0;
}
if(!mCurrentPool)
{
- apr_status_t status = apr_pool_create(&mCurrentPool, mPool);
- (void)ll_apr_warn_status(status);
+ mCurrentPool.create(mPool);
}
// add all of the file descriptors
run_it = mRunningChains.begin();
LLChainInfo::conditionals_t::iterator fd_it;
LLChainInfo::conditionals_t::iterator fd_end;
- apr_pollset_create(&mPollset, size, mCurrentPool, 0);
+ apr_pollset_create(&mPollset, size, mCurrentPool(), 0);
for(; run_it != run_end; ++run_it)
{
fd_it = (*run_it).mDescriptors.begin();
@@ -1157,7 +1132,8 @@ bool LLPumpIO::handleChainError(
LLPumpIO::LLChainInfo::LLChainInfo() :
mInit(false),
mLock(0),
- mEOS(false)
+ mEOS(false),
+ mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool))
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 9303c9d7fc..75c35ae7ab 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -30,11 +30,12 @@
#define LL_LLPUMPIO_H
#include <set>
+#include <boost/shared_ptr.hpp>
#if LL_LINUX // needed for PATH_MAX in APR.
#include <sys/param.h>
#endif
-#include "apr_pools.h"
+#include "llaprpool.h"
#include "llbuffer.h"
#include "llframetimer.h"
#include "lliopipe.h"
@@ -58,9 +59,8 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS;
* <code>pump()</code> on a thread used for IO and call
* <code>respond()</code> on a thread that is expected to do higher
* level processing. You can call almost any other method from any
- * thread - see notes for each method for details. In order for the
- * threading abstraction to work, you need to call <code>prime()</code>
- * with a valid apr pool.
+ * thread - see notes for each method for details.
+ *
* A pump instance manages much of the state for the pipe, including
* the list of pipes in the chain, the channel for each element in the
* chain, the buffer, and if any pipe has marked the stream or process
@@ -79,7 +79,7 @@ public:
/**
* @brief Constructor.
*/
- LLPumpIO(apr_pool_t* pool);
+ LLPumpIO(void);
/**
* @brief Destructor.
@@ -87,17 +87,6 @@ public:
~LLPumpIO();
/**
- * @brief Prepare this pump for usage.
- *
- * If you fail to call this method prior to use, the pump will
- * try to work, but will not come with any thread locking
- * mechanisms.
- * @param pool The apr pool to use.
- * @return Returns true if the pump is primed.
- */
- bool prime(apr_pool_t* pool);
-
- /**
* @brief Typedef for having a chain of pipes.
*/
typedef std::vector<LLIOPipe::ptr_t> chain_t;
@@ -368,6 +357,7 @@ protected:
typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t;
typedef std::vector<pipe_conditional_t> conditionals_t;
conditionals_t mDescriptors;
+ boost::shared_ptr<LLAPRPool> mDescriptorsPool;
};
// All the running chains & info
@@ -386,9 +376,9 @@ protected:
callbacks_t mPendingCallbacks;
callbacks_t mCallbacks;
- // memory allocator for pollsets & mutexes.
- apr_pool_t* mPool;
- apr_pool_t* mCurrentPool;
+ // Memory pool for pollsets & mutexes.
+ LLAPRPool mPool;
+ LLAPRPool mCurrentPool;
S32 mCurrentPoolReallocCount;
#if LL_THREADS_APR
@@ -400,8 +390,7 @@ protected:
#endif
protected:
- void initialize(apr_pool_t* pool);
- void cleanup();
+ void initialize();
/**
* @brief Given the internal state of the chains, rebuild the pollset
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index cb9d1c3731..83b6f7cf71 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -40,6 +40,7 @@
#include "llstring.h"
#include "apr_env.h"
#include "llapr.h"
+#include "llscopedvolatileaprpool.h"
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
/**
@@ -210,27 +211,31 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
// is called with use_proxy = FALSE
void LLURLRequest::useProxy(bool use_proxy)
{
- static char *env_proxy;
+ static std::string env_proxy;
- if (use_proxy && (env_proxy == NULL))
+ if (use_proxy && env_proxy.empty())
{
- apr_status_t status;
- LLAPRPool pool;
- status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
+ char* env_proxy_str;
+ LLScopedVolatileAPRPool scoped_pool;
+ apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool);
if (status != APR_SUCCESS)
{
- status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
+ status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool);
}
if (status != APR_SUCCESS)
{
- use_proxy = FALSE;
+ use_proxy = false;
}
+ else
+ {
+ // env_proxy_str is stored in the scoped_pool, so we have to make a copy.
+ env_proxy = env_proxy_str;
+ }
}
+ lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl;
- lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;
-
- if (env_proxy && use_proxy)
+ if (use_proxy)
{
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
}
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 2f0d815be5..302cfc7ca2 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -97,8 +97,10 @@ std::string get_shared_secret();
class LLMessagePollInfo
{
public:
+ LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
apr_socket_t *mAPRSocketp;
apr_pollfd_t mPollFD;
+ LLAPRPool mPool;
};
namespace
@@ -287,20 +289,13 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
}
// LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl;
- //
- // Create the data structure that we can poll on
- //
- if (!gAPRPoolp)
- {
- LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
- ll_init_apr();
- }
+ mPollInfop = new LLMessagePollInfo;
+
apr_socket_t *aprSocketp = NULL;
- apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
+ apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
- mPollInfop = new LLMessagePollInfo;
mPollInfop->mAPRSocketp = aprSocketp;
- mPollInfop->mPollFD.p = gAPRPoolp;
+ mPollInfop->mPollFD.p = mPollInfop->mPool();
mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
mPollInfop->mPollFD.reqevents = APR_POLLIN;
mPollInfop->mPollFD.rtnevents = 0;
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 2aff90ca1e..23e1c791f4 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -30,7 +30,6 @@
#define LL_NETWORKIO_H
#include "llmemory.h" // LLSingleton
-#include "llapr.h"
#include "llares.h"
#include "llpumpio.h"
#include "llhttpclient.h"
@@ -48,14 +47,8 @@ public:
mServicePump(NULL),
mDone(false)
{
- ll_init_apr();
- if (! gAPRPoolp)
- {
- throw std::runtime_error("Can't initialize APR");
- }
-
// Create IO Pump to use for HTTP Requests.
- mServicePump = new LLPumpIO(gAPRPoolp);
+ mServicePump = new LLPumpIO;
LLHTTPClient::setPump(*mServicePump);
if (ll_init_ares() == NULL || !gAres->isInitialized())
{
diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp
index c326961db4..9c9909a017 100644
--- a/indra/llplugin/llplugininstance.cpp
+++ b/indra/llplugin/llplugininstance.cpp
@@ -29,8 +29,7 @@
#include "linden_common.h"
#include "llplugininstance.h"
-
-#include "llapr.h"
+#include "llthread.h" // Needed for LLThread::tldata().mRootPool
/** Virtual destructor. */
LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
@@ -48,6 +47,7 @@ const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoin
* @param[in] owner Plugin instance. TODO:DOC is this a good description of what "owner" is?
*/
LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) :
+ mDSOHandlePool(LLThread::tldata().mRootPool),
mDSOHandle(NULL),
mPluginUserData(NULL),
mPluginSendMessageFunction(NULL)
@@ -79,7 +79,7 @@ int LLPluginInstance::load(std::string &plugin_file)
int result = apr_dso_load(&mDSOHandle,
plugin_file.c_str(),
- gAPRPoolp);
+ mDSOHandlePool());
if(result != APR_SUCCESS)
{
char buf[1024];
diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h
index 50531ca77f..1c3898e2e7 100644
--- a/indra/llplugin/llplugininstance.h
+++ b/indra/llplugin/llplugininstance.h
@@ -30,6 +30,7 @@
#include "llstring.h"
#include "llapr.h"
+#include "llaprpool.h"
#include "apr_dso.h"
@@ -88,6 +89,7 @@ private:
static void staticReceiveMessage(const char *message_string, void **user_data);
void receiveMessage(const char *message_string);
+ LLAPRPool mDSOHandlePool;
apr_dso_handle_t *mDSOHandle;
void *mPluginUserData;
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 8d13e38ad5..dd47300b9c 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -92,8 +92,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
}
LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
- mInputMutex(gAPRPoolp),
- mOutputMutex(gAPRPoolp),
mOwner(owner),
mSocket(socket)
{
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index 45a86476ac..2fa5dcdd01 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -40,7 +40,7 @@ LLPluginProcessChild::LLPluginProcessChild()
{
mState = STATE_UNINITIALIZED;
mInstance = NULL;
- mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ mSocket = LLSocket::create(LLSocket::STREAM_TCP);
mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz
mCPUElapsed = 0.0f;
mBlockingRequest = false;
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index c002de0462..eaf7ec4bf3 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -33,6 +33,7 @@
#include "llpluginmessageclasses.h"
#include "llapr.h"
+#include "llscopedvolatileaprpool.h"
//virtual
LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
@@ -42,6 +43,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
bool LLPluginProcessParent::sUseReadThread = false;
apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
+LLAPRPool LLPluginProcessParent::sPollSetPool;
bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
LLMutex *LLPluginProcessParent::sInstancesMutex;
std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
@@ -52,7 +54,7 @@ class LLPluginProcessParentPollThread: public LLThread
{
public:
LLPluginProcessParentPollThread() :
- LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
+ LLThread("LLPluginProcessParentPollThread")
{
}
protected:
@@ -77,12 +79,11 @@ protected:
};
-LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
- mIncomingQueueMutex(gAPRPoolp)
+LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner)
{
if(!sInstancesMutex)
{
- sInstancesMutex = new LLMutex(gAPRPoolp);
+ sInstancesMutex = new LLMutex;
}
mOwner = owner;
@@ -95,6 +96,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
mBlocked = false;
mPolledInput = false;
mPollFD.client_data = NULL;
+ mPollFDPool.create();
mPluginLaunchTimeout = 60.0f;
mPluginLockupTimeout = 15.0f;
@@ -169,44 +171,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
bool LLPluginProcessParent::accept()
{
bool result = false;
-
apr_status_t status = APR_EGENERAL;
- apr_socket_t *new_socket = NULL;
-
- status = apr_socket_accept(
- &new_socket,
- mListenSocket->getSocket(),
- gAPRPoolp);
+ mSocket = LLSocket::create(status, mListenSocket);
if(status == APR_SUCCESS)
{
// llinfos << "SUCCESS" << llendl;
// Success. Create a message pipe on the new socket
-
- // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
- apr_pool_t* new_pool = NULL;
- status = apr_pool_create(&new_pool, gAPRPoolp);
-
- mSocket = LLSocket::create(new_socket, new_pool);
new LLPluginMessagePipe(this, mSocket);
result = true;
}
- else if(APR_STATUS_IS_EAGAIN(status))
- {
-// llinfos << "EAGAIN" << llendl;
-
- // No incoming connections. This is not an error.
- status = APR_SUCCESS;
- }
else
{
-// llinfos << "Error:" << llendl;
- ll_apr_warn_status(status);
-
- // Some other error.
- errorState();
+ mSocket.reset();
+ // EAGAIN means "No incoming connections". This is not an error.
+ if (!APR_STATUS_IS_EAGAIN(status))
+ {
+ // Some other error.
+ ll_apr_warn_status(status);
+ errorState();
+ }
}
return result;
@@ -272,10 +258,10 @@ void LLPluginProcessParent::idle(void)
case STATE_INITIALIZED:
{
-
apr_status_t status = APR_SUCCESS;
+ LLScopedVolatileAPRPool addr_pool;
apr_sockaddr_t* addr = NULL;
- mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ mListenSocket = LLSocket::create(LLSocket::STREAM_TCP);
mBoundPort = 0;
// This code is based on parts of LLSocket::create() in lliosocket.cpp.
@@ -286,7 +272,7 @@ void LLPluginProcessParent::idle(void)
APR_INET,
0, // port 0 = ephemeral ("find me a port")
0,
- gAPRPoolp);
+ addr_pool);
if(ll_apr_warn_status(status))
{
@@ -598,7 +584,7 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
if(message_pipe != NULL)
{
// Set up the apr_pollfd_t
- mPollFD.p = gAPRPoolp;
+ mPollFD.p = mPollFDPool();
mPollFD.desc_type = APR_POLL_SOCKET;
mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
mPollFD.rtnevents = 0;
@@ -645,6 +631,7 @@ void LLPluginProcessParent::updatePollset()
// delete the existing pollset.
apr_pollset_destroy(sPollSet);
sPollSet = NULL;
+ sPollSetPool.destroy();
}
std::list<LLPluginProcessParent*>::iterator iter;
@@ -667,12 +654,14 @@ void LLPluginProcessParent::updatePollset()
{
#ifdef APR_POLLSET_NOCOPY
// The pollset doesn't exist yet. Create it now.
- apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY);
+ sPollSetPool.create();
+ apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
if(status != APR_SUCCESS)
{
#endif // APR_POLLSET_NOCOPY
LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL;
sPollSet = NULL;
+ sPollSetPool.destroy();
#ifdef APR_POLLSET_NOCOPY
}
else
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 32394809ef..6beeb64c7e 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -176,7 +176,9 @@ private:
static bool sUseReadThread;
apr_pollfd_t mPollFD;
+ LLAPRPool mPollFDPool;
static apr_pollset_t *sPollSet;
+ static LLAPRPool sPollSetPool;
static bool sPollsetNeedsRebuild;
static LLMutex *sInstancesMutex;
static std::list<LLPluginProcessParent*> sInstances;
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp
index 63ff5085c6..e2ff645a9c 100644
--- a/indra/llplugin/llpluginsharedmemory.cpp
+++ b/indra/llplugin/llpluginsharedmemory.cpp
@@ -187,7 +187,8 @@ bool LLPluginSharedMemory::create(size_t size)
mName += createName();
mSize = size;
- apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
+ mPool.create();
+ apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool());
if(ll_apr_warn_status(status))
{
@@ -210,7 +211,7 @@ bool LLPluginSharedMemory::destroy(void)
}
mImpl->mAprSharedMemory = NULL;
}
-
+ mPool.destroy();
return true;
}
@@ -219,7 +220,8 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
mName = name;
mSize = size;
- apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
+ mPool.create();
+ apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() );
if(ll_apr_warn_status(status))
{
@@ -241,6 +243,7 @@ bool LLPluginSharedMemory::detach(void)
}
mImpl->mAprSharedMemory = NULL;
}
+ mPool.destroy();
return true;
}
diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h
index c6cd49cabb..84b7a58c32 100644
--- a/indra/llplugin/llpluginsharedmemory.h
+++ b/indra/llplugin/llpluginsharedmemory.h
@@ -28,6 +28,8 @@
#ifndef LL_LLPLUGINSHAREDMEMORY_H
#define LL_LLPLUGINSHAREDMEMORY_H
+#include "llaprpool.h"
+
class LLPluginSharedMemoryPlatformImpl;
/**
@@ -108,6 +110,7 @@ private:
bool close(void);
bool unlink(void);
+ LLAPRPool mPool;
std::string mName;
size_t mSize;
void *mMappedAddress;
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 516a58db88..ff86e4e135 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -176,8 +176,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
int main(int argc, char **argv)
#endif
{
- ll_init_apr();
-
// Set up llerror logging
{
LLError::initForApplication(".");
@@ -393,8 +391,6 @@ int main(int argc, char **argv)
delete plugin;
- ll_cleanup_apr();
-
return 0;
}
diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp
index 3d3ed9f6d4..bf49b9668e 100644
--- a/indra/llvfs/lllfsthread.cpp
+++ b/indra/llvfs/lllfsthread.cpp
@@ -67,10 +67,6 @@ LLLFSThread::LLLFSThread(bool threaded) :
LLQueuedThread("LFS", threaded),
mPriorityCounter(PRIORITY_LOWBITS)
{
- if(!mLocalAPRFilePoolp)
- {
- mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
- }
}
LLLFSThread::~LLLFSThread()
@@ -182,8 +178,7 @@ bool LLLFSThread::Request::processRequest()
if (mOperation == FILE_READ)
{
llassert(mOffset >= 0);
- LLAPRFile infile ; // auto-closes
- infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool());
+ LLAPRFile infile(mFileName, LL_APR_RB);
if (!infile.getFileHandle())
{
llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
@@ -205,8 +200,7 @@ bool LLLFSThread::Request::processRequest()
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
if (mOffset < 0)
flags |= APR_APPEND;
- LLAPRFile outfile ; // auto-closes
- outfile.open(mFileName, flags, mThread->getLocalAPRFilePool());
+ LLAPRFile outfile(mFileName, flags);
if (!outfile.getFileHandle())
{
llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index c1fe21c57d..1a64623028 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
mDataFP(NULL),
mIndexFP(NULL)
{
- mDataMutex = new LLMutex(0);
+ mDataMutex = new LLMutex;
S32 i;
for (i = 0; i < VFSLOCK_COUNT; i++)
@@ -2094,8 +2094,7 @@ void LLVFS::dumpFiles()
std::string filename = id.asString() + extension;
llinfos << " Writing " << filename << llendl;
- LLAPRFile outfile;
- outfile.open(filename, LL_APR_WB);
+ LLAPRFile outfile(filename, LL_APR_WB);
outfile.write(&buffer[0], size);
outfile.close();
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
index 6bc272c009..77d6d19663 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
@@ -37,7 +37,6 @@ extern "C" {
#include <stdio.h>
#include <gst/gst.h>
-#include "apr_pools.h"
#include "apr_dso.h"
}
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
index 2e4baaa9eb..93a10424dd 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
@@ -28,16 +28,18 @@
#if LL_GSTREAMER010_ENABLED
+#include "linden_common.h"
+
#include <string>
extern "C" {
#include <gst/gst.h>
-#include "apr_pools.h"
#include "apr_dso.h"
}
#include "llmediaimplgstreamertriviallogging.h"
+#include "llaprpool.h"
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
#include "llmediaimplgstreamer_syms_raw.inc"
@@ -56,7 +58,7 @@ void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
}
static bool sSymsGrabbed = false;
-static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
+static LLAPRPool sSymGSTDSOMemoryPool;
static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
@@ -78,11 +80,11 @@ bool grab_gst_syms(std::string gst_dso_name,
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0)
//attempt to load the shared libraries
- apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
+ sSymGSTDSOMemoryPool.create();
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
gst_dso_name.c_str(),
- sSymGSTDSOMemoryPool) ))
+ sSymGSTDSOMemoryPool()) ))
{
INFOMSG("Found DSO: %s", gst_dso_name.c_str());
#include "llmediaimplgstreamer_syms_raw.inc"
@@ -96,7 +98,7 @@ bool grab_gst_syms(std::string gst_dso_name,
if ( APR_SUCCESS ==
(rv = apr_dso_load(&sSymGSTDSOHandle,
gst_dso_name_vid.c_str(),
- sSymGSTDSOMemoryPool) ))
+ sSymGSTDSOMemoryPool()) ))
{
INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str());
#include "llmediaimplgstreamer_syms_rawv.inc"
@@ -150,8 +152,7 @@ void ungrab_gst_syms()
if ( sSymGSTDSOMemoryPool )
{
- apr_pool_destroy(sSymGSTDSOMemoryPool);
- sSymGSTDSOMemoryPool = NULL;
+ sSymGSTDSOMemoryPool.destroy();
}
// NULL-out all of the symbols we'd grabbed
diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp
index 91be3a89e9..94dfd80700 100644
--- a/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/linux_volume_catcher.cpp
@@ -65,7 +65,7 @@ extern "C" {
#undef LL_PA_SYM
static bool sSymsGrabbed = false;
-static apr_pool_t *sSymPADSOMemoryPool = NULL;
+static LLAPRPool sSymPADSOMemoryPool;
static apr_dso_handle_t *sSymPADSOHandleG = NULL;
bool grab_pa_syms(std::string pulse_dso_name)
@@ -84,11 +84,11 @@ bool grab_pa_syms(std::string pulse_dso_name)
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
//attempt to load the shared library
- apr_pool_create(&sSymPADSOMemoryPool, NULL);
+ sSymPADSOMemoryPool.create();
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
pulse_dso_name.c_str(),
- sSymPADSOMemoryPool) ))
+ sSymPADSOMemoryPool()) ))
{
INFOMSG("Found DSO: %s", pulse_dso_name.c_str());
@@ -130,12 +130,8 @@ void ungrab_pa_syms()
apr_dso_unload(sSymPADSOHandleG);
sSymPADSOHandleG = NULL;
}
-
- if ( sSymPADSOMemoryPool )
- {
- apr_pool_destroy(sSymPADSOMemoryPool);
- sSymPADSOMemoryPool = NULL;
- }
+
+ sSymPADSOMemoryPool.destroy();
// NULL-out all of the symbols we'd grabbed
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a23f809b71..1f76e2af40 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1026,7 +1026,7 @@ bool LLAppViewer::mainLoop()
//-------------------------------------------
// Create IO Pump to use for HTTP Requests.
- gServicePump = new LLPumpIO(gAPRPoolp);
+ gServicePump = new LLPumpIO;
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
@@ -1387,16 +1387,16 @@ bool LLAppViewer::cleanup()
}
// *TODO - generalize this and move DSO wrangling to a helper class -brad
- std::set<struct apr_dso_handle_t *>::const_iterator i;
- for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
+ for(std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> >::iterator plugin = mPlugins.begin();
+ plugin != mPlugins.end(); ++plugin)
{
int (*ll_plugin_stop_func)(void) = NULL;
- apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
+ apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, plugin->first, "ll_plugin_stop");
ll_plugin_stop_func();
- rv = apr_dso_unload(*i);
+ rv = apr_dso_unload(plugin->first);
}
- mPlugins.clear();
+ mPlugins.clear(); // Forget handles and destroy all memory pools.
//flag all elements as needing to be destroyed immediately
// to ensure shutdown order
@@ -1828,7 +1828,7 @@ bool LLAppViewer::initThreads()
if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
{
- LLFastTimer::sLogLock = new LLMutex(NULL);
+ LLFastTimer::sLogLock = new LLMutex;
mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);
mFastTimerLogThread->start();
}
@@ -2969,8 +2969,7 @@ void LLAppViewer::handleViewerCrash()
else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
llinfos << "Creating crash marker file " << crash_file_name << llendl;
- LLAPRFile crash_file ;
- crash_file.open(crash_file_name, LL_APR_W);
+ LLAPRFile crash_file(crash_file_name, LL_APR_W);
if (crash_file.getFileHandle())
{
LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
@@ -3034,11 +3033,10 @@ bool LLAppViewer::anotherInstanceRunning()
LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
//Freeze case checks
- if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
+ if (LLAPRFile::isExist(marker_file, LL_APR_RB))
{
// File exists, try opening with write permissions
- LLAPRFile outfile ;
- outfile.open(marker_file, LL_APR_WB);
+ LLAPRFile outfile(marker_file, LL_APR_WB);
apr_file_t* fMarker = outfile.getFileHandle() ;
if (!fMarker)
{
@@ -3077,25 +3075,25 @@ void LLAppViewer::initMarkerFile()
std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
- if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
+ if (LLAPRFile::isExist(mMarkerFileName, LL_APR_RB) && !anotherInstanceRunning())
{
gLastExecEvent = LAST_EXEC_FROZE;
LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
}
- if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
+ if(LLAPRFile::isExist(logout_marker_file, LL_APR_RB))
{
gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
LLAPRFile::remove(logout_marker_file);
}
- if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
+ if(LLAPRFile::isExist(llerror_marker_file, LL_APR_RB))
{
if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
else gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
LLAPRFile::remove(llerror_marker_file);
}
- if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ if(LLAPRFile::isExist(error_marker_file, LL_APR_RB))
{
if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
@@ -3111,7 +3109,7 @@ void LLAppViewer::initMarkerFile()
// Create the marker file for this execution & lock it
apr_status_t s;
- s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
+ s = mMarkerFile.open(mMarkerFileName, LL_APR_W, LLAPRFile::long_lived);
if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
{
@@ -4327,8 +4325,7 @@ void LLAppViewer::sendLogoutRequest()
gLogoutInProgress = TRUE;
mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
- LLAPRFile outfile ;
- outfile.open(mLogoutMarkerFileName, LL_APR_W);
+ LLAPRFile outfile(mLogoutMarkerFileName, LL_APR_W);
mLogoutMarkerFile = outfile.getFileHandle() ;
if (mLogoutMarkerFile)
{
@@ -4778,14 +4775,15 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
}
#endif // LL_WINDOWS
- apr_dso_handle_t * eventhost_dso_handle = NULL;
- apr_pool_t * eventhost_dso_memory_pool = NULL;
+ boost::shared_ptr<LLAPRPool> eventhost_dso_memory_pool_ptr(new LLAPRPool);
+ LLAPRPool& eventhost_dso_memory_pool(*eventhost_dso_memory_pool_ptr);
+ apr_dso_handle_t* eventhost_dso_handle = NULL;
//attempt to load the shared library
- apr_pool_create(&eventhost_dso_memory_pool, NULL);
+ eventhost_dso_memory_pool.create();
apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
dso_path.c_str(),
- eventhost_dso_memory_pool);
+ eventhost_dso_memory_pool());
llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
llassert_always(eventhost_dso_handle != NULL);
@@ -4805,7 +4803,8 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
llerrs << "problem loading eventhost plugin, status: " << status << llendl;
}
- mPlugins.insert(eventhost_dso_handle);
+ // Store the handle and link it to the pool that was used to allocate it.
+ mPlugins[eventhost_dso_handle] = eventhost_dso_memory_pool_ptr;
}
void LLAppViewer::launchUpdater()
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index a18e6cbb02..00b12d50ae 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -266,7 +266,7 @@ private:
LLAllocator mAlloc;
- std::set<struct apr_dso_handle_t*> mPlugins;
+ std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> > mPlugins;
U32 mAvailPhysicalMemInKB ;
U32 mAvailVirtualMemInKB ;
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 898cc1c0ba..d4c6131c80 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -110,6 +110,7 @@ int main( int argc, char **argv )
}
delete viewer_app_ptr;
viewer_app_ptr = NULL;
+
return 0;
}
diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp
index 32e7e0a83d..1ae469dfcf 100644
--- a/indra/newview/llappviewerlinux_api_dbus.cpp
+++ b/indra/newview/llappviewerlinux_api_dbus.cpp
@@ -27,11 +27,11 @@
#if LL_DBUS_ENABLED
#include "linden_common.h"
+#include "llaprpool.h"
extern "C" {
#include <dbus/dbus-glib.h>
-#include "apr_pools.h"
#include "apr_dso.h"
}
@@ -44,7 +44,7 @@ extern "C" {
#undef LL_DBUS_SYM
static bool sSymsGrabbed = false;
-static apr_pool_t *sSymDBUSDSOMemoryPool = NULL;
+static LLAPRPool sSymDBUSDSOMemoryPool;
static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL;
bool grab_dbus_syms(std::string dbus_dso_name)
@@ -63,11 +63,11 @@ bool grab_dbus_syms(std::string dbus_dso_name)
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0)
//attempt to load the shared library
- apr_pool_create(&sSymDBUSDSOMemoryPool, NULL);
+ sSymDBUSDSOMemoryPool.create();
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle,
dbus_dso_name.c_str(),
- sSymDBUSDSOMemoryPool) ))
+ sSymDBUSDSOMemoryPool()) ))
{
INFOMSG("Found DSO: %s", dbus_dso_name.c_str());
@@ -109,11 +109,7 @@ void ungrab_dbus_syms()
sSymDBUSDSOHandleG = NULL;
}
- if ( sSymDBUSDSOMemoryPool )
- {
- apr_pool_destroy(sSymDBUSDSOMemoryPool);
- sSymDBUSDSOMemoryPool = NULL;
- }
+ sSymDBUSDSOMemoryPool.destroy();
// NULL-out all of the symbols we'd grabbed
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0)
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 1cd80986d8..13c8745eaf 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -113,6 +113,7 @@ int main( int argc, char **argv )
}
delete viewer_app_ptr;
viewer_app_ptr = NULL;
+
return 0;
}
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index deebd69ec1..9b96332c10 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -223,8 +223,7 @@ BOOL LLFloaterAnimPreview::postBuild()
// now load bvh file
S32 file_size;
- LLAPRFile infile ;
- infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size);
+ LLAPRFile infile(mFilenameAndPath, LL_APR_RB, &file_size);
if (!infile.getFileHandle())
{
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index 5c020e6d98..d73048a28b 100644
--- a/indra/newview/llmainlooprepeater.cpp
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void)
{
if(mQueue != 0) return;
- mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
+ mQueue = new LLThreadSafeQueue<LLSD>(1024);
mMainLoopConnection = LLEventPumps::instance().
obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
mRepeaterConnection = LLEventPumps::instance().
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index f54214b95c..a47ea8581a 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -176,7 +176,7 @@ private:
bool LLTextureCacheLocalFileWorker::doRead()
{
- S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
+ S32 local_size = LLAPRFile::size(mFileName);
if (local_size > 0 && mFileName.size() > 4)
{
@@ -250,7 +250,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
}
mReadData = new U8[mDataSize];
- S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
+ S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize);
if (bytes_read != mDataSize)
{
@@ -331,7 +331,7 @@ bool LLTextureCacheRemoteWorker::doRead()
// Is it a JPEG2000 file?
{
local_filename = filename + ".j2c";
- local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+ local_size = LLAPRFile::size(local_filename);
if (local_size > 0)
{
mImageFormat = IMG_CODEC_J2C;
@@ -341,7 +341,7 @@ bool LLTextureCacheRemoteWorker::doRead()
if (local_size == 0)
{
local_filename = filename + ".jpg";
- local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+ local_size = LLAPRFile::size(local_filename);
if (local_size > 0)
{
mImageFormat = IMG_CODEC_JPEG;
@@ -352,7 +352,7 @@ bool LLTextureCacheRemoteWorker::doRead()
if (local_size == 0)
{
local_filename = filename + ".tga";
- local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+ local_size = LLAPRFile::size(local_filename);
if (local_size > 0)
{
mImageFormat = IMG_CODEC_TGA;
@@ -378,8 +378,7 @@ bool LLTextureCacheRemoteWorker::doRead()
}
// Allocate read buffer
mReadData = new U8[mDataSize];
- S32 bytes_read = LLAPRFile::readEx(local_filename,
- mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
+ S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize);
if (bytes_read != mDataSize)
{
llwarns << "Error reading file from local cache: " << local_filename
@@ -430,8 +429,7 @@ bool LLTextureCacheRemoteWorker::doRead()
size = llmin(size, mDataSize);
// Allocate the read buffer
mReadData = new U8[size];
- S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName,
- mReadData, offset, size, mCache->getLocalAPRFilePool());
+ S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, mReadData, offset, size);
if (bytes_read != size)
{
llwarns << "LLTextureCacheWorker: " << mID
@@ -457,7 +455,7 @@ bool LLTextureCacheRemoteWorker::doRead()
if (!done && (mState == BODY))
{
std::string filename = mCache->getTextureFileName(mID);
- S32 filesize = LLAPRFile::size(filename, mCache->getLocalAPRFilePool());
+ S32 filesize = LLAPRFile::size(filename);
if (filesize && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset)
{
@@ -499,8 +497,7 @@ bool LLTextureCacheRemoteWorker::doRead()
// Read the data at last
S32 bytes_read = LLAPRFile::readEx(filename,
mReadData + data_offset,
- file_offset, file_size,
- mCache->getLocalAPRFilePool());
+ file_offset, file_size);
if (bytes_read != file_size)
{
llwarns << "LLTextureCacheWorker: " << mID
@@ -601,13 +598,13 @@ bool LLTextureCacheRemoteWorker::doWrite()
U8* padBuffer = new U8[TEXTURE_CACHE_ENTRY_SIZE];
memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros
memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer
- bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
+ bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size);
delete [] padBuffer;
}
else
{
// Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file
- bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
+ bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size);
}
if (bytes_written <= 0)
@@ -642,8 +639,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
// llinfos << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << llendl;
S32 bytes_written = LLAPRFile::writeEx( filename,
mWriteData + TEXTURE_CACHE_ENTRY_SIZE,
- 0, file_size,
- mCache->getLocalAPRFilePool());
+ 0, file_size);
if (bytes_written <= 0)
{
llwarns << "LLTextureCacheWorker: " << mID
@@ -740,9 +736,6 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted)
LLTextureCache::LLTextureCache(bool threaded)
: LLWorkerThread("TextureCache", threaded),
- mWorkersMutex(NULL),
- mHeaderMutex(NULL),
- mListMutex(NULL),
mHeaderAPRFile(NULL),
mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.
mTexturesSizeTotal(0),
@@ -846,7 +839,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
// Is it a JPEG2000 file?
{
local_filename = filename + ".j2c";
- local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+ local_size = LLAPRFile::size(local_filename);
if (local_size > 0)
{
return TRUE ;
@@ -856,7 +849,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
// If not, is it a jpeg file?
{
local_filename = filename + ".jpg";
- local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+ local_size = LLAPRFile::size(local_filename);
if (local_size > 0)
{
return TRUE ;
@@ -866,7 +859,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
// Hmm... What about a targa file? (used for UI texture mostly)
{
local_filename = filename + ".tga";
- local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+ local_size = LLAPRFile::size(local_filename);
if (local_size > 0)
{
return TRUE ;
@@ -912,10 +905,10 @@ void LLTextureCache::purgeCache(ELLPath location)
if(LLFile::isdir(mTexturesDirName))
{
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ LLAPRFile::remove(file_name);
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ LLAPRFile::remove(file_name);
purgeAllTextures(true);
}
@@ -991,7 +984,9 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
{
llassert_always(mHeaderAPRFile == NULL);
apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY;
- mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
+ // All code calling openHeaderEntriesFile, immediately calls closeHeaderEntriesFile,
+ // so this file is very short-lived.
+ mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags);
if(offset > 0)
{
mHeaderAPRFile->seek(APR_SET, offset);
@@ -1014,10 +1009,9 @@ void LLTextureCache::readEntriesHeader()
{
// mHeaderEntriesInfo initializes to default values so safe not to read it
llassert_always(mHeaderAPRFile == NULL);
- if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
+ if (LLAPRFile::isExist(mHeaderEntriesFileName))
{
- LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
}
else //create an empty entries header.
{
@@ -1032,8 +1026,7 @@ void LLTextureCache::writeEntriesHeader()
llassert_always(mHeaderAPRFile == NULL);
if (!mReadOnly)
{
- LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
}
}
@@ -1623,7 +1616,7 @@ void LLTextureCache::purgeTextures(bool validate)
if (uuididx == validate_idx)
{
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
- S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
+ S32 bodysize = LLAPRFile::size(filename);
if (bodysize != entries[idx].mBodySize)
{
LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
@@ -1858,7 +1851,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
mTexturesSizeMap.erase(id);
}
mHeaderIDMap.erase(id);
- LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());
+ LLAPRFile::remove(getTextureFileName(id));
}
//called after mHeaderMutex is locked.
@@ -1870,7 +1863,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
{
if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0.
{
- if (LLAPRFile::isExist(filename, getLocalAPRFilePool())) // Sanity check. Shouldn't exist when body size is 0.
+ if (LLAPRFile::isExist(filename)) // Sanity check. Shouldn't exist when body size is 0.
{
LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
}
@@ -1891,7 +1884,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
if (file_maybe_exists)
{
- LLAPRFile::remove(filename, getLocalAPRFilePool());
+ LLAPRFile::remove(filename);
}
}
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 64e3a2658c..79f5ba5835 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -142,9 +142,6 @@ protected:
std::string getTextureFileName(const LLUUID& id);
void addCompleted(Responder* responder, bool success);
-protected:
- //void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; }
-
private:
void setDirNames(ELLPath location);
void readHeaderCache();
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 18c3a3b87d..139b434aeb 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -674,7 +674,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mRetryAttempt(0),
mActiveCount(0),
mGetStatus(0),
- mWorkMutex(NULL),
mFirstPacket(0),
mLastPacket(-1),
mTotalPackets(0),
@@ -1816,8 +1815,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mDebugPause(FALSE),
mPacketCount(0),
mBadPacketCount(0),
- mQueueMutex(getAPRPool()),
- mNetworkQueueMutex(getAPRPool()),
mTextureCache(cache),
mImageDecodeThread(imagedecodethread),
mTextureBandwidth(0),
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index fda291f3c1..6bee7556cd 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -736,8 +736,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
uuid = tid.makeAssetID(gAgent.getSecureSessionID());
// copy this file into the vfs for upload
S32 file_size;
- LLAPRFile infile ;
- infile.open(filename, LL_APR_RB, NULL, &file_size);
+ LLAPRFile infile(filename, LL_APR_RB, &file_size);
if (infile.getFileHandle())
{
LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index fd89044995..2cd9b09932 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7190,8 +7190,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
// static
void LLVOAvatar::dumpArchetypeXML( void* )
{
- LLAPRFile outfile;
- outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB );
+ LLAPRFile outfile(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER, "new archetype.xml"), LL_APR_WB);
apr_file_t* file = outfile.getFileHandle() ;
if (!file)
{
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index a933500706..d25831b4f1 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -30,14 +30,14 @@
#include "llregionhandle.h"
#include "llviewercontrol.h"
-BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
+static BOOL check_read(LLAPRFile& apr_file, void* src, S32 n_bytes)
{
- return apr_file->read(src, n_bytes) == n_bytes ;
+ return apr_file.read(src, n_bytes) == n_bytes ;
}
-BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
+static BOOL check_write(LLAPRFile& apr_file, void* src, S32 n_bytes)
{
- return apr_file->write(src, n_bytes) == n_bytes ;
+ return apr_file.write(src, n_bytes) == n_bytes ;
}
@@ -70,7 +70,7 @@ LLVOCacheEntry::LLVOCacheEntry()
mDP.assignBuffer(mBuffer, 0);
}
-LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
+LLVOCacheEntry::LLVOCacheEntry(LLAPRFile& apr_file)
{
S32 size = -1;
BOOL success;
@@ -185,7 +185,7 @@ void LLVOCacheEntry::dump() const
<< llendl;
}
-BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
+BOOL LLVOCacheEntry::writeToFile(LLAPRFile& apr_file) const
{
BOOL success;
success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
@@ -266,7 +266,6 @@ LLVOCache::LLVOCache():
mCacheSize(1)
{
mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
- mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
}
LLVOCache::~LLVOCache()
@@ -276,7 +275,6 @@ LLVOCache::~LLVOCache()
writeCacheHeader();
clearCacheInMemory();
}
- delete mLocalAPRFilePoolp;
}
void LLVOCache::setDirNames(ELLPath location)
@@ -437,7 +435,7 @@ void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
std::string filename;
getObjectCacheFilename(entry->mHandle, filename);
- LLAPRFile::remove(filename, mLocalAPRFilePoolp);
+ LLAPRFile::remove(filename);
entry->mTime = INVALID_TIME ;
updateEntry(entry) ; //update the head file.
}
@@ -454,12 +452,12 @@ void LLVOCache::readCacheHeader()
clearCacheInMemory();
bool success = true ;
- if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
+ if (LLAPRFile::isExist(mHeaderFileName))
{
- LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+ LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY);
//read the meta element
- success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
+ success = check_read(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
if(success)
{
@@ -472,7 +470,7 @@ void LLVOCache::readCacheHeader()
{
entry = new HeaderEntryInfo() ;
}
- success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo));
+ success = check_read(apr_file, entry, sizeof(HeaderEntryInfo));
if(!success) //failed
{
@@ -541,17 +539,17 @@ void LLVOCache::writeCacheHeader()
bool success = true ;
{
- LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+ LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY);
//write the meta element
- success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
+ success = check_write(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
mNumEntries = 0 ;
for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
{
(*iter)->mIndex = mNumEntries++ ;
- success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
+ success = check_write(apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
}
mNumEntries = mHeaderEntryQueue.size() ;
@@ -562,7 +560,7 @@ void LLVOCache::writeCacheHeader()
for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)
{
//fill the cache with the default entry.
- success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;
+ success = check_write(apr_file, entry, sizeof(HeaderEntryInfo)) ;
}
delete entry ;
@@ -579,10 +577,10 @@ void LLVOCache::writeCacheHeader()
BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
{
- LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
- apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
+ LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY);
+ apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo));
- return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
+ return check_write(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
}
void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
@@ -605,10 +603,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
{
std::string filename;
getObjectCacheFilename(handle, filename);
- LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+ LLAPRFile apr_file(filename, APR_READ|APR_BINARY);
LLUUID cache_id ;
- success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
+ success = check_read(apr_file, cache_id.mData, UUID_BYTES) ;
if(success)
{
@@ -621,11 +619,11 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
if(success)
{
S32 num_entries;
- success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
+ success = check_read(apr_file, &num_entries, sizeof(S32)) ;
for (S32 i = 0; success && i < num_entries; i++)
{
- LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file);
+ LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);
if (!entry->getLocalID())
{
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
@@ -724,19 +722,19 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
{
std::string filename;
getObjectCacheFilename(handle, filename);
- LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+ LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY);
- success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
+ success = check_write(apr_file, (void*)id.mData, UUID_BYTES) ;
if(success)
{
S32 num_entries = cache_entry_map.size() ;
- success = check_write(&apr_file, &num_entries, sizeof(S32));
+ success = check_write(apr_file, &num_entries, sizeof(S32));
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
{
- success = iter->second->writeToFile(&apr_file) ;
+ success = iter->second->writeToFile(apr_file) ;
}
}
}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 14e3b4c793..76456b9e98 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -41,7 +41,7 @@ class LLVOCacheEntry
{
public:
LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
- LLVOCacheEntry(LLAPRFile* apr_file);
+ LLVOCacheEntry(LLAPRFile& apr_file);
LLVOCacheEntry();
~LLVOCacheEntry();
@@ -51,7 +51,7 @@ public:
S32 getCRCChangeCount() const { return mCRCChangeCount; }
void dump() const;
- BOOL writeToFile(LLAPRFile* apr_file) const;
+ BOOL writeToFile(LLAPRFile& apr_file) const;
void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);
LLDataPackerBinaryBuffer *getDP(U32 crc);
void recordHit();
@@ -142,7 +142,6 @@ private:
U32 mNumEntries;
std::string mHeaderFileName ;
std::string mObjectCacheDirName;
- LLVolatileAPRPool* mLocalAPRFilePoolp ;
header_entry_queue_t mHeaderEntryQueue;
handle_entry_map_t mHandleEntryMap;
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 08e242af8e..828207ce1a 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -961,7 +961,7 @@ void LLVivoxVoiceClient::stateMachine()
if(!mSocket)
{
- mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ mSocket = LLSocket::create(LLSocket::STREAM_TCP);
}
mConnected = mSocket->blockingConnect(mDaemonHost);
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 1694126802..d982ca5020 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -178,8 +178,8 @@ void LLWatchdog::init(killer_event_callback func)
mKillerCallback = func;
if(!mSuspectsAccessMutex && !mTimer)
{
- mSuspectsAccessMutex = new LLMutex(NULL);
- mTimer = new LLWatchdogTimerThread();
+ mSuspectsAccessMutex = new LLMutex;
+ mTimer = new LLWatchdogTimerThread;
mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
mLastClockCount = LLTimer::getTotalTime();
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index acc6e814bc..102294959a 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -27,7 +27,6 @@
// Dependencies
#include "linden_common.h"
-#include "llapr.h"
#include "llsingleton.h"
#include "lltrans.h"
#include "lluistring.h"
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp
index 09beb53869..532f26ee60 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -29,7 +29,6 @@
#include "linden_common.h"
#include "lltut.h"
-#include "llapr.h"
#include "llmessagetemplate.h"
#include "llquaternion.h"
#include "lltemplatemessagebuilder.h"
@@ -53,7 +52,6 @@ namespace tut
static bool init = false;
if(! init)
{
- ll_init_apr();
const F32 circuit_heartbeat_interval=5;
const F32 circuit_timeout=100;
diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp
index d971b33475..9a6ccd4d68 100644
--- a/indra/test/message_tut.cpp
+++ b/indra/test/message_tut.cpp
@@ -29,7 +29,6 @@
#include "linden_common.h"
#include "lltut.h"
-#include "llapr.h"
#include "llmessageconfig.h"
#include "llsdserialize.h"
#include "llversionserver.h"
@@ -62,7 +61,6 @@ namespace tut
static bool init = false;
if(!init)
{
- ll_init_apr();
//init_prehash_data();
init = true;
}
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index ffdb0cb976..45e8aef99a 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -37,8 +37,8 @@
#include "linden_common.h"
#include "llerrorcontrol.h"
#include "lltut.h"
+#include "llaprpool.h"
-#include "apr_pools.h"
#include "apr_getopt.h"
// the CTYPE_WORKAROUND is needed for linux dev stations that don't
@@ -349,17 +349,12 @@ int main(int argc, char **argv)
ctype_workaround();
#endif
- apr_initialize();
- apr_pool_t* pool = NULL;
- if(APR_SUCCESS != apr_pool_create(&pool, NULL))
- {
- std::cerr << "Unable to initialize pool" << std::endl;
- return 1;
- }
+ LLAPRPool pool;
+ pool.create();
apr_getopt_t* os = NULL;
- if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
+ if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv))
{
- std::cerr << "Unable to pool" << std::endl;
+ std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl;
return 1;
}
@@ -477,8 +472,6 @@ int main(int argc, char **argv)
s.close();
}
- apr_terminate();
-
int retval = (success ? 0 : 1);
return retval;
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 4a2272032b..fd46626ff1 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -27,7 +27,6 @@
#include "linden_common.h"
#include "indra_constants.h"
-#include "llapr.h"
#include "llerrorcontrol.h"
#include <math.h>
@@ -186,9 +185,6 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind
std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
};
- // initialize linden lab APR module
- ll_init_apr();
-
// Set up llerror logging
{
LLError::initForApplication(".");
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index d450c068ad..6aa87d1be6 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -26,6 +26,7 @@
#include "linden_common.h"
#include <apr_file_io.h>
#include "llapr.h"
+#include "llscopedvolatileaprpool.h"
#include "llprocesslauncher.h"
#include "llupdateinstaller.h"
#include "lldir.h"
@@ -45,7 +46,8 @@ namespace {
{
std::string scriptFile = gDirUtilp->getBaseFileName(path);
std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile);
- apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp);
+ LLScopedVolatileAPRPool pool;
+ apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, pool);
if(status != APR_SUCCESS) throw RelocateError();
return newPath;