From 4331c112aba074562e9a8826fe6d271a94f790f0 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 14 Oct 2011 11:52:40 -0500
Subject: [PATCH] Backed out changeset b782a75c99e6

---
 doc/contributions.txt                         |   9 +-
 indra/llaudio/llaudioengine_fmod.cpp          |   2 +-
 indra/llaudio/llvorbisencode.cpp              |   9 +-
 indra/llcharacter/llbvhloader.cpp             |   3 +-
 indra/llcharacter/llkeyframemotionparam.cpp   |   3 +-
 indra/llcharacter/llstatemachine.cpp          |   3 +-
 indra/llcommon/CMakeLists.txt                 |   3 -
 indra/llcommon/llapp.cpp                      |   4 +
 indra/llcommon/llapr.cpp                      | 445 ++++++++++++++----
 indra/llcommon/llapr.h                        | 107 ++++-
 indra/llcommon/llaprpool.cpp                  | 202 --------
 indra/llcommon/llaprpool.h                    | 256 ----------
 indra/llcommon/llcommon.cpp                   |  13 +
 indra/llcommon/llcommon.h                     |   2 +
 indra/llcommon/llerror.cpp                    |   3 -
 indra/llcommon/llerror.h                      |   1 +
 indra/llcommon/llfixedbuffer.cpp              |   3 +-
 indra/llcommon/llscopedvolatileaprpool.h      |  52 --
 indra/llcommon/llthread.cpp                   | 151 +++---
 indra/llcommon/llthread.h                     | 124 ++---
 indra/llcommon/llthreadsafequeue.cpp          |  15 +-
 indra/llcommon/llthreadsafequeue.h            |  16 +-
 indra/llcommon/llworkerthread.cpp             |   8 +-
 indra/llcommon/llworkerthread.h               |   3 +-
 indra/llcrashlogger/llcrashlogger.cpp         |   3 +-
 indra/llimage/llimage.cpp                     |   8 +-
 indra/llimage/llimagedimensionsinfo.cpp       |   2 +-
 indra/llimage/llimagej2c.cpp                  |   3 +-
 indra/llimage/llimageworker.cpp               |   8 +-
 indra/llimage/llimageworker.h                 |   2 +-
 indra/llmath/llvolumemgr.cpp                  |   4 +-
 indra/llmessage/llares.cpp                    |  17 +-
 indra/llmessage/llcurl.cpp                    |   2 +-
 indra/llmessage/lliohttpserver.cpp            |  10 +-
 indra/llmessage/lliohttpserver.h              |   2 +-
 indra/llmessage/lliosocket.cpp                |  99 ++--
 indra/llmessage/lliosocket.h                  |  33 +-
 indra/llmessage/llmail.cpp                    |  17 +-
 indra/llmessage/llmail.h                      |   4 +-
 indra/llmessage/llpumpio.cpp                  |  74 ++-
 indra/llmessage/llpumpio.h                    |  31 +-
 indra/llmessage/llurlrequest.cpp              |  25 +-
 indra/llmessage/message.cpp                   |  17 +-
 indra/llmessage/tests/networkio.h             |   9 +-
 indra/llplugin/llplugininstance.cpp           |   6 +-
 indra/llplugin/llplugininstance.h             |   2 -
 indra/llplugin/llpluginmessagepipe.cpp        |   2 +
 indra/llplugin/llpluginprocesschild.cpp       |   2 +-
 indra/llplugin/llpluginprocessparent.cpp      |  57 ++-
 indra/llplugin/llpluginprocessparent.h        |   2 -
 indra/llplugin/llpluginsharedmemory.cpp       |   9 +-
 indra/llplugin/llpluginsharedmemory.h         |   3 -
 indra/llplugin/slplugin/slplugin.cpp          |   4 +
 indra/llvfs/lllfsthread.cpp                   |  10 +-
 indra/llvfs/llvfs.cpp                         |   5 +-
 .../gstreamer010/llmediaimplgstreamer.h       |   1 +
 .../llmediaimplgstreamer_syms.cpp             |  15 +-
 .../webkit/linux_volume_catcher.cpp           |  14 +-
 indra/newview/llappviewer.cpp                 |  47 +-
 indra/newview/llappviewer.h                   |   2 +-
 indra/newview/llappviewerlinux.cpp            |   1 -
 indra/newview/llappviewerlinux_api_dbus.cpp   |  14 +-
 indra/newview/llappviewermacosx.cpp           |   1 -
 indra/newview/llfloateranimpreview.cpp        |   3 +-
 indra/newview/llmainlooprepeater.cpp          |   2 +-
 indra/newview/lltexturecache.cpp              |  61 +--
 indra/newview/lltexturecache.h                |   3 +
 indra/newview/lltexturefetch.cpp              |   3 +
 indra/newview/llviewermenufile.cpp            |   3 +-
 indra/newview/llvoavatar.cpp                  |   3 +-
 indra/newview/llvocache.cpp                   |  54 ++-
 indra/newview/llvocache.h                     |   5 +-
 indra/newview/llvoicevivox.cpp                |   2 +-
 indra/newview/llwatchdog.cpp                  |   4 +-
 indra/newview/tests/llworldmap_test.cpp       |   1 +
 indra/test/lltemplatemessagebuilder_tut.cpp   |   2 +
 indra/test/message_tut.cpp                    |   2 +
 indra/test/test.cpp                           |  17 +-
 .../llplugintest/llmediaplugintest.cpp        |   4 +
 .../updater/llupdateinstaller.cpp             |   4 +-
 80 files changed, 1080 insertions(+), 1097 deletions(-)
 delete mode 100644 indra/llcommon/llaprpool.cpp
 delete mode 100644 indra/llcommon/llaprpool.h
 delete mode 100644 indra/llcommon/llscopedvolatileaprpool.h

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 03e4978dd06..8765240caa2 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -61,15 +61,11 @@ 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
@@ -90,8 +86,11 @@ 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 88dfdb9c244..a40de9fa68b 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, LL_APR_RPB))
+	if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
 	{
 		// File not found, abort.
 		return false;
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 44eeea0ca41..0e0c80a4567 100644
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -82,7 +82,8 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
 	error_msg.clear();
 
 	//********************************
-	LLAPRFile infile(in_fname, LL_APR_RB);
+	LLAPRFile infile ;
+    infile.open(in_fname,LL_APR_RB);
 	//********************************
 	if (!infile.getFileHandle())
 	{
@@ -232,7 +233,8 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
 
 	S32 data_left = 0;
 
-	LLAPRFile infile(in_fname,LL_APR_RB);
+	LLAPRFile infile ;
+	infile.open(in_fname,LL_APR_RB);
 	if (!infile.getFileHandle())
 	{
 		llwarns << "Couldn't open temporary ogg file for writing: " << in_fname
@@ -240,7 +242,8 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
 		return(LLVORBISENC_SOURCE_OPEN_ERR);
 	}
 
-	LLAPRFile outfile(out_fname, LL_APR_WPB);
+	LLAPRFile outfile ;
+	outfile.open(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 a39a344684c..532a2c1b0d7 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -219,7 +219,8 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
 	//--------------------------------------------------------------------
 	std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
 
-	LLAPRFile infile(path, LL_APR_R);
+	LLAPRFile infile ;
+	infile.open(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 c3d5dec8754..82fe8971f5a 100644
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
@@ -351,7 +351,8 @@ BOOL LLKeyframeMotionParam::loadMotions()
 	// open the file
 	//-------------------------------------------------------------------------
 	S32 fileSize = 0;
-	LLAPRFile infile(path, LL_APR_R, &fileSize);
+	LLAPRFile infile ;
+	infile.open(path, LL_APR_R, NULL, &fileSize);
 	apr_file_t* fp = infile.getFileHandle() ;
 	if (!fp || fileSize == 0)
 	{
diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp
index dcc4ff5f0e7..e0454131a52 100644
--- a/indra/llcharacter/llstatemachine.cpp
+++ b/indra/llcharacter/llstatemachine.cpp
@@ -204,7 +204,8 @@ LLFSMState* LLStateDiagram::getState(U32 state_id)
 
 BOOL LLStateDiagram::saveDotFile(const std::string& filename)
 {
-	LLAPRFile outfile(filename, LL_APR_W);
+	LLAPRFile outfile ;
+	outfile.open(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 d5b0a67533a..9342a22d46f 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -32,7 +32,6 @@ set(llcommon_SOURCE_FILES
     llallocator_heap_profile.cpp
     llapp.cpp
     llapr.cpp
-    llaprpool.cpp
     llassettype.cpp
     llavatarname.cpp
     llbase32.cpp
@@ -81,7 +80,6 @@ set(llcommon_SOURCE_FILES
     llrand.cpp
     llrefcount.cpp
     llrun.cpp
-    llscopedvolatileaprpool.h
     llsd.cpp
     llsdserialize.cpp
     llsdserialize_xml.cpp
@@ -123,7 +121,6 @@ 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 e5bd2bfa3da..39daefd1ad6 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -136,6 +136,10 @@ 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 1e4a51102e7..d1c44c94032 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -29,8 +29,212 @@
 #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
@@ -109,17 +313,15 @@ void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle)
 //
 LLAPRFile::LLAPRFile()
 	: mFile(NULL),
-	  mVolatileFilePoolp(NULL),
-	  mRegularFilePoolp(NULL)
+	  mCurrentFilePoolp(NULL)
 {
 }
 
-LLAPRFile::LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep, access_t access_type)
+LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool)
 	: mFile(NULL),
-	  mVolatileFilePoolp(NULL),
-	  mRegularFilePoolp(NULL)
+	  mCurrentFilePoolp(NULL)
 {
-	open(filename, flags, access_type, sizep);
+	open(filename, flags, pool);
 }
 
 LLAPRFile::~LLAPRFile()
@@ -136,58 +338,36 @@ apr_status_t LLAPRFile::close()
 		mFile = NULL ;
 	}
 
-	if (mVolatileFilePoolp)
+	if(mCurrentFilePoolp)
 	{
-		mVolatileFilePoolp->clearVolatileAPRPool() ;
-		mVolatileFilePoolp = NULL ;
-	}
-
-	if (mRegularFilePoolp)
-	{
-		delete mRegularFilePoolp;
-		mRegularFilePoolp = NULL;
+		mCurrentFilePoolp->clearVolatileAPRPool() ;
+		mCurrentFilePoolp = NULL ;
 	}
 
 	return ret ;
 }
 
-apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep)
+apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep)
 {
-	llassert_always(!mFile);
-	llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp);
+	apr_status_t s ;
 
-	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)
+	//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));
+
+	if (s != APR_SUCCESS || !mFile)
 	{
 		mFile = NULL ;
-		close() ;
+		
 		if (sizep)
 		{
 			*sizep = 0;
 		}
-		return status;
 	}
-
-	if (sizep)
+	else if (sizep)
 	{
 		S32 file_size = 0;
 		apr_off_t offset = 0;
@@ -201,7 +381,49 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc
 		*sizep = file_size;
 	}
 
-	return status;
+	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 ;
 }
 
 // File I/O
@@ -259,6 +481,45 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
 //static components of LLAPRFile
 //
 
+//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)
 {
@@ -292,15 +553,13 @@ 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)
+S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
 {
-	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)
+	//*****************************************
+	apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY); 
+	//*****************************************	
+	if (!file_handle)
 	{
-		ll_apr_warn_status(s);
-		LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
 		return 0;
 	}
 
@@ -330,13 +589,14 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
 		}
 	}
 	
-	apr_file_close(file_handle);
-
+	//*****************************************
+	close(file_handle, pool) ; 
+	//*****************************************
 	return (S32)bytes_read;
 }
 
 //static
-S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
+S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
 {
 	apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
 	if (offset < 0)
@@ -345,13 +605,11 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
 		offset = 0;
 	}
 	
-	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)
+	//*****************************************
+	apr_file_t* file_handle = open(filename, pool, flags);
+	//*****************************************
+	if (!file_handle)
 	{
-		ll_apr_warn_status(s);
-		LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
 		return 0;
 	}
 
@@ -381,18 +639,21 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
 		}
 	}
 
-	apr_file_close(file_handle);
+	//*****************************************
+	LLAPRFile::close(file_handle, pool);
+	//*****************************************
 
 	return (S32)bytes_written;
 }
 
 //static
-bool LLAPRFile::remove(const std::string& filename)
+bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
 {
 	apr_status_t s;
 
-	LLScopedVolatileAPRPool pool;
-	s = apr_file_remove(filename.c_str(), pool);
+	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
+	s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool());
+	pool->clearVolatileAPRPool() ;
 
 	if (s != APR_SUCCESS)
 	{
@@ -404,12 +665,13 @@ bool LLAPRFile::remove(const std::string& filename)
 }
 
 //static
-bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
+bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
 {
 	apr_status_t s;
 
-	LLScopedVolatileAPRPool pool;
-	s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
+	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
+	s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool());
+	pool->clearVolatileAPRPool() ;
 	
 	if (s != APR_SUCCESS)
 	{
@@ -421,44 +683,49 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
 }
 
 //static
-bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags)
+bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
 {
-	apr_file_t* file_handle;
+	apr_file_t* apr_file;
 	apr_status_t s;
 
-	LLScopedVolatileAPRPool pool;
-	s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
+	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
+	s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());	
 
-	if (s != APR_SUCCESS || !file_handle)
+	if (s != APR_SUCCESS || !apr_file)
 	{
+		pool->clearVolatileAPRPool() ;
 		return false;
 	}
 	else
 	{
-		apr_file_close(file_handle);
+		apr_file_close(apr_file) ;
+		pool->clearVolatileAPRPool() ;
 		return true;
 	}
 }
 
 //static
-S32 LLAPRFile::size(const std::string& filename)
+S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
 {
-	apr_file_t* file_handle;
+	apr_file_t* apr_file;
 	apr_finfo_t info;
 	apr_status_t s;
 	
-	LLScopedVolatileAPRPool pool;
-	s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
+	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
+	s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool());
 	
-	if (s != APR_SUCCESS || !file_handle)
+	if (s != APR_SUCCESS || !apr_file)
 	{		
+		pool->clearVolatileAPRPool() ;
+		
 		return 0;
 	}
 	else
 	{
-		apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, file_handle);
+		apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);		
 
-		apr_file_close(file_handle) ;
+		apr_file_close(apr_file) ;
+		pool->clearVolatileAPRPool() ;
 		
 		if (s == APR_SUCCESS)
 		{
@@ -472,29 +739,31 @@ S32 LLAPRFile::size(const std::string& filename)
 }
 
 //static
-bool LLAPRFile::makeDir(const std::string& dirname)
+bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
 {
 	apr_status_t s;
 
-	LLScopedVolatileAPRPool pool;
-	s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
+	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
+	s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool());
+	pool->clearVolatileAPRPool() ;
 		
 	if (s != APR_SUCCESS)
 	{
 		ll_apr_warn_status(s);
-		LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL;
+		LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;
 		return false;
 	}
 	return true;
 }
 
 //static
-bool LLAPRFile::removeDir(const std::string& dirname)
+bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
 {
 	apr_status_t s;
 
-	LLScopedVolatileAPRPool pool;
-	s = apr_file_remove(dirname.c_str(), pool);
+	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
+	s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool());
+	pool->clearVolatileAPRPool() ;
 	
 	if (s != APR_SUCCESS)
 	{
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 3f846f13145..af33ce666f1 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -50,9 +50,71 @@
 #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;
-class LLAPRPool;
-class LLVolatileAPRPool;
+
+/** 
+ * @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 LLScopedLock
@@ -143,20 +205,15 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
 	// make this non copyable since a copy closes the file
 private:
 	apr_file_t* mFile ;
-	LLVolatileAPRPool* mVolatileFilePoolp;	// (Thread local) APR pool currently in use.
-	LLAPRPool* mRegularFilePoolp;		// ...or a regular pool.
+	LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp 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(std::string const& filename, apr_int32_t flags, S32* sizep = NULL, access_t access_type = short_lived);
+	LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL);
 	~LLAPRFile() ;
-
-	apr_status_t open(const std::string& filename, apr_int32_t flags, access_t access_type, S32* sizep = NULL);
+	
+	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 close() ;
 
 	// Returns actual offset, -1 if seek fails
@@ -169,24 +226,32 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
 	
 	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);
-	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);
+	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);
 
 	// Returns bytes read/written, 0 if read/write fails:
-	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
+	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
 //*******************************************************************************************************************************
 };
 
@@ -202,4 +267,6 @@ 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
deleted file mode 100644
index 6f21b61b65e..00000000000
--- a/indra/llcommon/llaprpool.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @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
deleted file mode 100644
index bf4102c5849..00000000000
--- a/indra/llcommon/llaprpool.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * @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 b8a73948525..8be9e4f4de2 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -30,10 +30,18 @@
 #include "llmemory.h"
 #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();
@@ -47,5 +55,10 @@ 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 171590f3d80..ca9cad5d05e 100644
--- a/indra/llcommon/llcommon.h
+++ b/indra/llcommon/llcommon.h
@@ -35,6 +35,8 @@ 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 75048073ca4..bb64152407e 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -866,9 +866,6 @@ 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 15d167c32ed..4a42241c4f2 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -296,4 +296,5 @@ 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 4b5cdbe2885..d394f179fb5 100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
@@ -30,7 +30,8 @@
 
 LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
 	: LLLineBuffer(),
-	  mMaxLines(max_lines)
+	  mMaxLines(max_lines),
+	  mMutex(NULL)
 {
 	mTimer.reset();
 }
diff --git a/indra/llcommon/llscopedvolatileaprpool.h b/indra/llcommon/llscopedvolatileaprpool.h
deleted file mode 100644
index dbaf4edcad9..00000000000
--- a/indra/llcommon/llscopedvolatileaprpool.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @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 4917e3b9351..49d05ef4114 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -63,9 +63,6 @@ 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();
 
@@ -78,20 +75,38 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 }
 
 
-LLThread::LLThread(std::string const& name) :
-	mPaused(false),
+LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
+	mPaused(FALSE),
 	mName(name),
 	mAPRThreadp(NULL),
-	mStatus(STOPPED),
-	mThreadLocalData(NULL)
+	mStatus(STOPPED)
 {
-	mRunCondition = new LLCondition;
+	// 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 ;
 }
 
 
 LLThread::~LLThread()
 {
 	shutdown();
+
+	if(mLocalAPRFilePoolp)
+	{
+		delete mLocalAPRFilePoolp ;
+		mLocalAPRFilePoolp = NULL ;
+	}
 }
 
 void LLThread::shutdown()
@@ -128,7 +143,7 @@ void LLThread::shutdown()
 		if (!isStopped())
 		{
 			// This thread just wouldn't stop, even though we gave it time
-			llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl;
+			llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
 			// Put a stake in its heart.
 			apr_thread_exit(mAPRThreadp, -1);
 			return;
@@ -138,8 +153,15 @@ void LLThread::shutdown()
 
 	delete mRunCondition;
 	mRunCondition = 0;
+	
+	if (mIsLocalPool && mAPRPoolp)
+	{
+		apr_pool_destroy(mAPRPoolp);
+		mAPRPoolp = 0;
+	}
 }
 
+
 void LLThread::start()
 {
 	llassert(isStopped());
@@ -148,7 +170,7 @@ void LLThread::start()
 	mStatus = RUNNING;
 
 	apr_status_t status =
-		apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
+		apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
 	
 	if(status == APR_SUCCESS)
 	{	
@@ -173,7 +195,7 @@ void LLThread::pause()
 	if (!mPaused)
 	{
 		// this will cause the thread to stop execution as soon as checkPause() is called
-		mPaused = true;		// Does not need to be atomic since this is only set/unset from the main thread
+		mPaused = 1;		// Does not need to be atomic since this is only set/unset from the main thread
 	}	
 }
 
@@ -181,7 +203,7 @@ void LLThread::unpause()
 {
 	if (mPaused)
 	{
-		mPaused = false;
+		mPaused = 0;
 	}
 
 	wake(); // wake up the thread if necessary
@@ -258,76 +280,85 @@ void LLThread::wakeLocked()
 	}
 }
 
-#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;
+//============================================================================
 
-//static
-void LLThreadLocalData::init(void)
+LLMutex::LLMutex(apr_pool_t *poolp) :
+	mAPRMutexp(NULL)
 {
-	// Only do this once.
-	if (sThreadLocalDataKey)
+	//if (poolp)
+	//{
+	//	mIsLocalPool = FALSE;
+	//	mAPRPoolp = poolp;
+	//}
+	//else
 	{
-		return;
+		mIsLocalPool = TRUE;
+		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
 	}
+	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
+}
 
-	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.
-
-	// 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();
+LLMutex::~LLMutex()
+{
+#if MUTEX_DEBUG
+	llassert_always(!isLocked()); // better not be locked!
 #endif
+	apr_thread_mutex_destroy(mAPRMutexp);
+	mAPRMutexp = NULL;
+	if (mIsLocalPool)
+	{
+		apr_pool_destroy(mAPRPoolp);
+	}
 }
 
-// This is called once for every thread when the thread is destructed.
-//static
-void LLThreadLocalData::destroy(void* thread_local_data)
+
+void LLMutex::lock()
 {
-	delete static_cast<LLThreadLocalData*>(thread_local_data);
+	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;
+#endif
 }
 
-//static
-void LLThreadLocalData::create(LLThread* threadp)
+void LLMutex::unlock()
 {
-	LLThreadLocalData* new_tld = new LLThreadLocalData;
-	if (threadp)
-	{
-		threadp->mThreadLocalData = new_tld;
-	}
-	apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey);
-	llassert_always(status == APR_SUCCESS);
+#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);
 }
 
-//static
-LLThreadLocalData& LLThreadLocalData::tldata(void)
+bool LLMutex::isLocked()
 {
-	if (!sThreadLocalDataKey)
+	apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
+	if (APR_STATUS_IS_EBUSY(status))
 	{
-		LLThreadLocalData::init();
+		return true;
+	}
+	else
+	{
+		apr_thread_mutex_unlock(mAPRMutexp);
+		return false;
 	}
-
-	void* data;
-	apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
-	llassert_always(status == APR_SUCCESS);
-	return *static_cast<LLThreadLocalData*>(data);
 }
 
 //============================================================================
 
-LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent)
+LLCondition::LLCondition(apr_pool_t *poolp) :
+	LLMutex(poolp)
 {
-	apr_thread_cond_create(&mAPRCondp, mPool());
+	// base class (LLMutex) has already ensured that mAPRPoolp is set up.
+
+	apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
 }
 
 
@@ -365,7 +396,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
 {
 	if (!sMutex)
 	{
-		sMutex = new LLMutex;
+		sMutex = new LLMutex(0);
 	}
 }
 
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 757832b8ca4..f1c6cd75af3 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -29,34 +29,12 @@
 
 #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:
@@ -67,7 +45,7 @@ class LL_COMMON_API LLThread
 		QUITTING= 2 	// Someone wants this thread to quit
 	} EThreadStatus;
 
-	LLThread(std::string const& name);
+	LLThread(const std::string& name, apr_pool_t *poolp = NULL);
 	virtual ~LLThread(); // Warning!  You almost NEVER want to destroy a thread unless it's in the STOPPED state.
 	virtual void shutdown(); // stops the thread
 	
@@ -82,7 +60,7 @@ class LL_COMMON_API LLThread
 	// Called from MAIN THREAD.
 	void pause();
 	void unpause();
-	bool isPaused() { return isStopped() || mPaused; }
+	bool isPaused() { return isStopped() || mPaused == TRUE; }
 	
 	// Cause the thread to wake up and check its condition
 	void wake();
@@ -96,11 +74,11 @@ class LL_COMMON_API LLThread
 	// this kicks off the apr thread
 	void start(void);
 
-	// Return thread-local data for the current thread.
-	static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
+	apr_pool_t *getAPRPool() { return mAPRPoolp; }
+	LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
 
 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);
@@ -110,10 +88,14 @@ class LL_COMMON_API LLThread
 	LLCondition*		mRunCondition;
 
 	apr_thread_t		*mAPRThreadp;
+	apr_pool_t			*mAPRPoolp;
+	BOOL				mIsLocalPool;
 	EThreadStatus		mStatus;
 
-	friend void LLThreadLocalData::create(LLThread* threadp);
-	LLThreadLocalData*	mThreadLocalData;
+	//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
+	//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
+	//      otherwise it will cause severe memory leaking!!! --bao
+	LLVolatileAPRPool  *mLocalAPRFilePoolp ; 
 
 	void setQuitting();
 	
@@ -143,80 +125,30 @@ class LL_COMMON_API LLThread
 
 #define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
 
-#ifdef MUTEX_DEBUG
-// We really shouldn't be using recursive locks. Make sure of that in debug mode.
-#define MUTEX_FLAG APR_THREAD_MUTEX_UNNESTED
-#else
-// Use the fastest platform-optimal lock behavior (can be recursive or non-recursive).
-#define MUTEX_FLAG APR_THREAD_MUTEX_DEFAULT
-#endif
-
-class LL_COMMON_API LLMutexBase
-{
-public:
-	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
+class LL_COMMON_API LLMutex
 {
 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;
-	}
-
+	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
+	
 protected:
-	LLAPRPool mPool;
-};
-
-#if APR_HAS_THREADS
-// No need to use a root pool in this case.
-typedef LLMutex LLMutexRootPool;
-#else // APR_HAS_THREADS
-class LL_COMMON_API LLMutexRootPool : public LLMutexBase
-{
-public:
-	LLMutexRootPool(void)
-	{
-		apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mRootPool());
-	}
-	~LLMutexRootPool()
-	{
-#if APR_POOL_DEBUG
-		// It is allowed to destruct root pools from a different thread.
-		mRootPool.grab_ownership();
+	apr_thread_mutex_t *mAPRMutexp;
+	apr_pool_t			*mAPRPoolp;
+	BOOL				mIsLocalPool;
+#if MUTEX_DEBUG
+	std::map<U32, BOOL> mIsLocked;
 #endif
-		llassert(!isLocked());
-		apr_thread_mutex_destroy(mAPRMutexp);
-		mAPRMutexp = NULL;
-	}
-
-protected:
-	LLAPRRootPool mRootPool;
 };
-#endif // APR_HAS_THREADS
 
 // Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
 class LL_COMMON_API LLCondition : public LLMutex
 {
 public:
-	LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool);
+	LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
 	~LLCondition();
 	
 	void wait();		// blocks
@@ -227,10 +159,10 @@ class LL_COMMON_API LLCondition : public LLMutex
 	apr_thread_cond_t *mAPRCondp;
 };
 
-class LL_COMMON_API LLMutexLock
+class LLMutexLock
 {
 public:
-	LLMutexLock(LLMutexBase* mutex)
+	LLMutexLock(LLMutex* mutex)
 	{
 		mMutex = mutex;
 		mMutex->lock();
@@ -240,7 +172,7 @@ class LL_COMMON_API LLMutexLock
 		mMutex->unlock();
 	}
 private:
-	LLMutexBase* mMutex;
+	LLMutex* mMutex;
 };
 
 //============================================================================
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index 05d24944f3e..8a73e632a9a 100644
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -34,11 +34,19 @@
 //-----------------------------------------------------------------------------
 
 
-LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(unsigned int capacity):
+LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
+	mOwnsPool(pool == 0),
+	mPool(pool),
 	mQueue(0)
 {
-	mPool.create();
-	apr_status_t status = apr_queue_create(&mQueue, capacity, mPool());
+	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);
 	if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
 }
 
@@ -51,6 +59,7 @@ 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 43d0b396f24..58cac38769c 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(unsigned int capacity);
+	LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
 	~LLThreadSafeQueueImplementation();
 	void pushFront(void * element);
 	bool tryPushFront(void * element);
@@ -84,7 +84,8 @@ class LL_COMMON_API LLThreadSafeQueueImplementation
 	size_t size();
 	
 private:
-	LLAPRPool mPool;			// The pool used for mQueue.
+	bool mOwnsPool;
+	apr_pool_t * mPool;
 	apr_queue_t * mQueue;
 };
 
@@ -98,8 +99,9 @@ class LLThreadSafeQueue
 public:
 	typedef ElementT value_type;
 	
-	// Constructor.
-	LLThreadSafeQueue(unsigned int capacity = 1024);
+	// 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);
 	
 	// Add an element to the front of queue (will block if the queue has
 	// reached capacity).
@@ -137,8 +139,8 @@ class LLThreadSafeQueue
 
 
 template<typename ElementT>
-LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(unsigned int capacity) :
-	mImplementation(capacity)
+LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
+	mImplementation(pool, capacity)
 {
 	; // No op.
 }
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 6b308bb9179..3ac50832fda 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -37,7 +37,12 @@
 LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) :
 	LLQueuedThread(name, threaded)
 {
-	mDeleteMutex = new LLMutex;
+	mDeleteMutex = new LLMutex(NULL);
+
+	if(!mLocalAPRFilePoolp)
+	{
+		mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
+	}
 }
 
 LLWorkerThread::~LLWorkerThread()
@@ -199,6 +204,7 @@ 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 bef5ef53fe4..9bff18303eb 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -94,6 +94,7 @@ class LL_COMMON_API LLWorkerThread : public LLQueuedThread
 
 private:
 	void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
+	
 };
 
 //============================================================================
@@ -193,7 +194,7 @@ class LL_COMMON_API LLWorkerClass
 	U32 mRequestPriority; // last priority set
 
 private:
-	LLMutexRootPool mMutex;		// Use LLMutexRootPool since this object is created and destructed by multiple threads.
+	LLMutex mMutex;
 	LLAtomicU32 mWorkFlags;
 };
 
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 8f7916f5655..68e45f36e4f 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -390,7 +390,8 @@ bool LLCrashLogger::init()
 		return false;
 	}
 
-	gServicePump = new LLPumpIO;
+	gServicePump = new LLPumpIO(gAPRPoolp);
+	gServicePump->prime(gAPRPoolp);
 	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 f4399d4ed41..39211bf7fa5 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;
+	sMutex = new LLMutex(NULL);
 }
 
 //static
@@ -1557,7 +1557,8 @@ BOOL LLImageFormatted::load(const std::string &filename)
 	resetLastError();
 
 	S32 file_size = 0;
-	LLAPRFile infile(filename, LL_APR_RB, &file_size);
+	LLAPRFile infile ;
+	infile.open(filename, LL_APR_RB, NULL, &file_size);
 	apr_file_t* apr_file = infile.getFileHandle();
 	if (!apr_file)
 	{
@@ -1592,7 +1593,8 @@ BOOL LLImageFormatted::save(const std::string &filename)
 {
 	resetLastError();
 
-	LLAPRFile outfile(filename, LL_APR_WB);
+	LLAPRFile outfile ;
+	outfile.open(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 8a10956a5b7..835664c60ff 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, LLAPRFile::long_lived, &file_size);
+	apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size);
 
 	if (s != APR_SUCCESS)
 	{
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 5f488a6764c..cb2a85fa917 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -358,7 +358,8 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
 	resetLastError();
 
 	S32 file_size = 0;
-	LLAPRFile infile(filename, LL_APR_RB, &file_size);
+	LLAPRFile infile ;
+	infile.open(filename, LL_APR_RB, NULL, &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 2c6d6f31ead..28dc3bd3133 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -35,18 +35,20 @@
 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)
 	{
@@ -69,7 +71,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;
@@ -79,7 +81,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 6a24b7522ab..c684222fa5f 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -98,7 +98,7 @@ class LLImageDecodeThread : public LLQueuedThread
 	};
 	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 734440d312a..88c195936cd 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;
+	//mDataMutex = new LLMutex(gAPRPoolp);
 }
 
 LLVolumeMgr::~LLVolumeMgr()
@@ -216,7 +216,7 @@ void LLVolumeMgr::useMutex()
 { 
 	if (!mDataMutex)
 	{
-		mDataMutex = new LLMutex;
+		mDataMutex = new LLMutex(gAPRPoolp);
 	}
 }
 
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index fab9858b697..5a67035ed15 100644
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -28,7 +28,6 @@
 
 #include "linden_common.h"
 #include "llares.h"
-#include "llscopedvolatileaprpool.h"
 
 #include <ares_dns.h>
 #include <ares_version.h>
@@ -465,6 +464,11 @@ 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;	
@@ -478,7 +482,10 @@ bool LLAres::process(U64 timeout)
 		return nsds > 0;
 	}
 
-	LLScopedVolatileAPRPool scoped_pool;
+	apr_status_t status;
+	LLAPRPool pool;
+	status = pool.getStatus() ;
+	ll_apr_assert_status(status);
 
 	for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
 	{
@@ -495,7 +502,7 @@ bool LLAres::process(U64 timeout)
 
 		apr_socket_t *aprSock = NULL;
 
-		apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
+		status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
 		if (status != APR_SUCCESS)
 		{
 			ll_apr_warn_status(status);
@@ -504,7 +511,7 @@ bool LLAres::process(U64 timeout)
 
 		aprFds[nactive].desc.s = aprSock;
 		aprFds[nactive].desc_type = APR_POLL_SOCKET;
-		aprFds[nactive].p = scoped_pool;
+		aprFds[nactive].p = pool.getAPRPool();
 		aprFds[nactive].rtnevents = 0;
 		aprFds[nactive].client_data = &socks[i];
 
@@ -513,7 +520,7 @@ bool LLAres::process(U64 timeout)
 
 	if (nactive > 0)
 	{
-		apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
+		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 4d3b382f7a6..a485fa01608 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);
+		sSSLMutex.push_back(new LLMutex(NULL));
 	}
 	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 d441492cf23..3b18a9177cf 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -954,9 +954,13 @@ class LLHTTPResponseFactory : public LLChainIOFactory
 
 
 // static
-LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
+LLHTTPNode& LLIOHTTPServer::create(
+	apr_pool_t* pool, LLPumpIO& pump, U16 port)
 {
-	LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port);
+	LLSocket::ptr_t socket = LLSocket::create(
+        pool,
+        LLSocket::STREAM_TCP,
+        port);
     if(!socket)
     {
         llerrs << "Unable to initialize socket" << llendl;
@@ -965,7 +969,7 @@ LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
     LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;
 	boost::shared_ptr<LLChainIOFactory> factory_ptr(factory);
 
-    LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr);
+    LLIOServerSocket* server = new LLIOServerSocket(pool, 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 2294e4b8ae2..5c1b0531ff2 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(LLPumpIO& pump, U16 port);
+	static LLHTTPNode& create(apr_pool_t* pool, 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 e802d9b3a6e..ca84fa8bb80 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -35,7 +35,6 @@
 #include "llhost.h"
 #include "llmemtype.h"
 #include "llpumpio.h"
-#include "llthread.h"
 
 //
 // constants
@@ -99,31 +98,51 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
 ///
 
 // static
-LLSocket::ptr_t LLSocket::create(EType type, U16 port)
+LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, 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;
-	LLSocket::ptr_t rv(new LLSocket);
+
+	// 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;
+	}
 
 	if(STREAM_TCP == type)
 	{
-		status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool());
+		status = apr_socket_create(
+			&socket,
+			APR_INET,
+			SOCK_STREAM,
+			APR_PROTO_TCP,
+			new_pool);
 	}
 	else if(DATAGRAM_UDP == type)
 	{
-		status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool());
+		status = apr_socket_create(
+			&socket,
+			APR_INET,
+			SOCK_DGRAM,
+			APR_PROTO_UDP,
+			new_pool);
 	}
 	else
 	{
-		rv.reset();
+		if(new_pool) apr_pool_destroy(new_pool);
 		return rv;
 	}
 	if(ll_apr_warn_status(status))
 	{
-		rv->mSocket = NULL;
-		rv.reset();
+		if(new_pool) apr_pool_destroy(new_pool);
 		return rv;
 	}
+	rv = ptr_t(new LLSocket(socket, new_pool));
 	if(port > 0)
 	{
 		apr_sockaddr_t* sa = NULL;
@@ -133,7 +152,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
 			APR_UNSPEC,
 			port,
 			0,
-			rv->mPool());
+			new_pool);
 		if(ll_apr_warn_status(status))
 		{
 			rv.reset();
@@ -141,8 +160,8 @@ LLSocket::ptr_t LLSocket::create(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(rv->mSocket, APR_SO_REUSEADDR, 1));
-		status = apr_socket_bind(rv->mSocket, sa);
+		ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1));
+		status = apr_socket_bind(socket, sa);
 		if(ll_apr_warn_status(status))
 		{
 			rv.reset();
@@ -156,7 +175,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
 			// to keep a queue of incoming connections for ACCEPT.
 			lldebugs << "Setting listen state for socket." << llendl;
 			status = apr_socket_listen(
-				rv->mSocket,
+				socket,
 				LL_DEFAULT_LISTEN_BACKLOG);
 			if(ll_apr_warn_status(status))
 			{
@@ -177,28 +196,21 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
 }
 
 // static
-LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
+LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_TCP);
-	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)
+	LLSocket::ptr_t rv;
+	if(!socket)
 	{
-		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;
@@ -211,7 +223,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
 		APR_UNSPEC,
 		host.getPort(),
 		0,
-		mPool())))
+		mPool)))
 	{
 		return false;
 	}
@@ -222,11 +234,13 @@ bool LLSocket::blockingConnect(const LLHost& host)
 	return true;
 }
 
-LLSocket::LLSocket() :
-	mSocket(NULL),
-	mPool(LLThread::tldata().mRootPool),
+LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) :
+	mSocket(socket),
+	mPool(pool),
 	mPort(PORT_INVALID)
 {
+	ll_debug_socket("Constructing wholely formed socket", mSocket);
+	LLMemType m1(LLMemType::MTYPE_IO_TCP);
 }
 
 LLSocket::~LLSocket()
@@ -238,6 +252,10 @@ LLSocket::~LLSocket()
 		ll_debug_socket("Destroying socket", mSocket);
 		apr_socket_close(mSocket);
 	}
+	if(mPool)
+	{
+		apr_pool_destroy(mPool);
+	}
 }
 
 void LLSocket::setOptions()
@@ -498,8 +516,10 @@ 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),
@@ -559,15 +579,21 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 	lldebugs << "accepting socket" << llendl;
 
 	PUMP_DEBUG;
-	apr_status_t status;
-	LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket));
+	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));
 	//EStatus rv = STATUS_ERROR;
-	if(llsocket && status == APR_SUCCESS)
+	if(llsocket)
 	{
 		PUMP_DEBUG;
 
 		apr_sockaddr_t* remote_addr;
-		apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket());
+		apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);
 		
 		char* remote_host_string;
 		apr_sockaddr_ip_get(&remote_host_string, remote_addr);
@@ -582,6 +608,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 		{
 			chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
 			pump->addChain(chain, mResponseTimeout);
+			status = STATUS_OK;
 		}
 		else
 		{
@@ -590,8 +617,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 	}
 	else
 	{
-		char buf[256];
-		llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl;
+		llwarns << "Unable to create linden socket." << llendl;
 	}
 
 	PUMP_DEBUG;
@@ -604,10 +630,11 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 #if 0
 LLIODataSocket::LLIODataSocket(
 	U16 suggested_port,
-	U16 start_discovery_port) :
+	U16 start_discovery_port,
+	apr_pool_t* pool) : 
 	mSocket(NULL)
 {
-	if(PORT_INVALID == suggested_port) return;
+	if(!pool || (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 1e352255123..6806e5084a4 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -38,6 +38,7 @@
  */
 
 #include "lliopipe.h"
+#include "apr_pools.h"
 #include "apr_network_io.h"
 #include "llchainio.h"
 
@@ -87,22 +88,34 @@ class LLSocket
 	 * 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 by accepting a connection from a listen socket.
+	 * @brief Create a LLSocket when you already have an apr socket.
 	 *
-	 * @param status Output. Status of the accept if a valid listen socket was passed.
-	 * @param listen_socket The listen socket to use.
+	 * 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.
 	 * @return A valid socket shared pointer if the call worked.
 	 */
-	static ptr_t create(apr_status_t& status, ptr_t& listen_socket);
+	static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
 
 	/** 
 	 * @brief Perform a blocking connect to a host. Do not use in production.
@@ -137,7 +150,7 @@ class LLSocket
 	 * @brief Protected constructor since should only make sockets
 	 * with one of the two <code>create()</code> calls.
 	 */
-	LLSocket(void);
+	LLSocket(apr_socket_t* socket, apr_pool_t* pool);
 
 	/** 
 	 * @brief Set default socket options.
@@ -154,8 +167,8 @@ class LLSocket
 	// The apr socket.
 	apr_socket_t* mSocket;
 
-	// Our memory pool.
-	LLAPRPool mPool;
+	// our memory pool
+	apr_pool_t* mPool;
 
 	// The port if we know it.
 	U16 mPort;
@@ -280,7 +293,7 @@ class LLIOServerSocket : public LLIOPipe
 public:
 	typedef LLSocket::ptr_t socket_t;
 	typedef boost::shared_ptr<LLChainIOFactory> factory_t;
-	LLIOServerSocket(socket_t listener, factory_t reactor);
+	LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);
 	virtual ~LLIOServerSocket();
 
 	/** 
@@ -312,6 +325,7 @@ class LLIOServerSocket : public LLIOPipe
 	//@}
 
 protected:
+	apr_pool_t* mPool;
 	socket_t mListenSocket;
 	factory_t mReactor;
 	bool mInitialized;
@@ -345,7 +359,8 @@ class LLIODataSocket : public LLIOSocket
 	 */
 	LLIODataSocket(
 		U16 suggested_port,
-		U16 start_discovery_port);
+		U16 start_discovery_port,
+		apr_pool_t* pool);
 	virtual ~LLIODataSocket();
 
 protected:
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 8a898ab1b0b..08b31e9c7a2 100644
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -50,7 +50,6 @@
 #include "llstring.h"
 #include "lluuid.h"
 #include "net.h"
-#include "llaprpool.h"
 
 //
 // constants
@@ -58,7 +57,7 @@
 const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
 
 static bool gMailEnabled = true;
-static LLAPRPool gMailPool;
+static apr_pool_t* gMailPool;
 static apr_sockaddr_t* gSockAddr;
 static apr_socket_t* gMailSocket;
 
@@ -83,7 +82,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))
@@ -140,19 +139,19 @@ BOOL LLMail::send(
 }
 
 // static
-void LLMail::init(const std::string& hostname)
+void LLMail::init(const std::string& hostname, apr_pool_t* pool)
 {
 	gMailSocket = NULL;
-	if (hostname.empty())
+	if(hostname.empty() || !pool)
 	{
+		gMailPool = NULL;
 		gSockAddr = NULL;
-		gMailPool.destroy();
 	}
 	else
 	{
-		gMailPool.create();
+		gMailPool = pool;
 
-		// Collect all the information into a sockaddr structure. the
+		// collect all the information into a socaddr sturcture. 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.
@@ -162,7 +161,7 @@ void LLMail::init(const std::string& hostname)
 			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 0a5c5320883..37917143639 100644
--- a/indra/llmessage/llmail.h
+++ b/indra/llmessage/llmail.h
@@ -27,13 +27,15 @@
 #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);
+	static void init(const std::string& hostname, apr_pool_t* pool);
 
 	// 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 89cfd66e1b2..a8d2a0a2240 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -37,7 +37,6 @@
 #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
@@ -163,12 +162,14 @@ struct ll_delete_apr_pollset_fd_client_data
 /**
  * LLPumpIO
  */
-LLPumpIO::LLPumpIO(void) :
+LLPumpIO::LLPumpIO(apr_pool_t* pool) :
 	mState(LLPumpIO::NORMAL),
 	mRebuildPollset(false),
 	mPollset(NULL),
 	mPollsetClientID(0),
 	mNextLock(0),
+	mPool(NULL),
+	mCurrentPool(NULL),
 	mCurrentPoolReallocCount(0),
 	mChainsMutex(NULL),
 	mCallbackMutex(NULL),
@@ -177,24 +178,21 @@ LLPumpIO::LLPumpIO(void) :
 	mCurrentChain = mRunningChains.end();
 
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-	initialize();
+	initialize(pool);
 }
 
 LLPumpIO::~LLPumpIO()
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-#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;
-	}
+	cleanup();
+}
+
+bool LLPumpIO::prime(apr_pool_t* pool)
+{
+	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
+	cleanup();
+	initialize(pool);
+	return ((pool == NULL) ? false : true);
 }
 
 bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
@@ -354,7 +352,8 @@ 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.
-		value.second.p = (*mCurrentChain).mDescriptorsPool->operator()();
+		// *FIX: Should it always be this pool?
+		value.second.p = mPool;
 	}
 	value.second.client_data = new S32(++mPollsetClientID);
 	(*mCurrentChain).mDescriptors.push_back(value);
@@ -826,15 +825,39 @@ void LLPumpIO::control(LLPumpIO::EControl op)
 	}
 }
 
-void LLPumpIO::initialize(void)
+void LLPumpIO::initialize(apr_pool_t* pool)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-	mPool.create();
+	if(!pool) return;
 #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, mPool());
-	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
+	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);
 #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()
@@ -862,19 +885,21 @@ void LLPumpIO::rebuildPollset()
 		if(mCurrentPool
 		   && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
 		{
-			mCurrentPool.destroy();
+			apr_pool_destroy(mCurrentPool);
+			mCurrentPool = NULL;
 			mCurrentPoolReallocCount = 0;
 		}
 		if(!mCurrentPool)
 		{
-			mCurrentPool.create(mPool);
+			apr_status_t status = apr_pool_create(&mCurrentPool, mPool);
+			(void)ll_apr_warn_status(status);
 		}
 
 		// 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();
@@ -1132,8 +1157,7 @@ bool LLPumpIO::handleChainError(
 LLPumpIO::LLChainInfo::LLChainInfo() :
 	mInit(false),
 	mLock(0),
-	mEOS(false),
-	mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool))
+	mEOS(false)
 {
 	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 75c35ae7ab9..9303c9d7fcf 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -30,12 +30,11 @@
 #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 "llaprpool.h"
+#include "apr_pools.h"
 #include "llbuffer.h"
 #include "llframetimer.h"
 #include "lliopipe.h"
@@ -59,8 +58,9 @@ 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.
- *
+ * 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.
  * 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,13 +79,24 @@ class LLPumpIO
 	/**
 	 * @brief Constructor.
 	 */
-	LLPumpIO(void);
+	LLPumpIO(apr_pool_t* pool);
 
 	/**
 	 * @brief Destructor.
 	 */
 	~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.
 	 */
@@ -357,7 +368,6 @@ class LLPumpIO
 		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
@@ -376,9 +386,9 @@ class LLPumpIO
 	callbacks_t mPendingCallbacks;
 	callbacks_t mCallbacks;
 
-	// Memory pool for pollsets & mutexes.
-	LLAPRPool mPool;
-	LLAPRPool mCurrentPool;
+	// memory allocator for pollsets & mutexes.
+	apr_pool_t* mPool;
+	apr_pool_t* mCurrentPool;
 	S32 mCurrentPoolReallocCount;
 
 #if LL_THREADS_APR
@@ -390,7 +400,8 @@ class LLPumpIO
 #endif
 
 protected:
-	void initialize();
+	void initialize(apr_pool_t* pool);
+	void cleanup();
 
 	/** 
 	 * @brief Given the internal state of the chains, rebuild the pollset
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 83b6f7cf719..cb9d1c3731f 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -40,7 +40,6 @@
 #include "llstring.h"
 #include "apr_env.h"
 #include "llapr.h"
-#include "llscopedvolatileaprpool.h"
 static const U32 HTTP_STATUS_PIPE_ERROR = 499;
 
 /**
@@ -211,31 +210,27 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
 // is called with use_proxy = FALSE
 void LLURLRequest::useProxy(bool use_proxy)
 {
-    static std::string env_proxy;
+    static char *env_proxy;
 
-    if (use_proxy && env_proxy.empty())
+    if (use_proxy && (env_proxy == NULL))
     {
-		char* env_proxy_str;
-        LLScopedVolatileAPRPool scoped_pool;
-        apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool);
+        apr_status_t status;
+        LLAPRPool pool;
+		status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
         if (status != APR_SUCCESS)
         {
-			status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool);
+			status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
         }
         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;
 
-    if (use_proxy)
+    lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;
+
+    if (env_proxy && use_proxy)
     {
 		mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
     }
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 302cfc7ca2f..2f0d815be52 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -97,10 +97,8 @@ 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
@@ -289,13 +287,20 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
 	}
 //	LL_DEBUGS("Messaging") <<  << "*** port: " << mPort << llendl;
 
-	mPollInfop = new LLMessagePollInfo;
-
+	//
+	// 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();
+	}
 	apr_socket_t *aprSocketp = NULL;
-	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
+	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
 
+	mPollInfop = new LLMessagePollInfo;
 	mPollInfop->mAPRSocketp = aprSocketp;
-	mPollInfop->mPollFD.p = mPollInfop->mPool();
+	mPollInfop->mPollFD.p = gAPRPoolp;
 	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 23e1c791f47..2aff90ca1ef 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -30,6 +30,7 @@
 #define LL_NETWORKIO_H
 
 #include "llmemory.h"               // LLSingleton
+#include "llapr.h"
 #include "llares.h"
 #include "llpumpio.h"
 #include "llhttpclient.h"
@@ -47,8 +48,14 @@ class NetworkIO: public LLSingleton<NetworkIO>
         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;
+        mServicePump = new LLPumpIO(gAPRPoolp);
         LLHTTPClient::setPump(*mServicePump);
         if (ll_init_ares() == NULL || !gAres->isInitialized())
         {
diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp
index 9c9909a0174..c326961db4a 100644
--- a/indra/llplugin/llplugininstance.cpp
+++ b/indra/llplugin/llplugininstance.cpp
@@ -29,7 +29,8 @@
 #include "linden_common.h"
 
 #include "llplugininstance.h"
-#include "llthread.h"			// Needed for LLThread::tldata().mRootPool
+
+#include "llapr.h"
 
 /** Virtual destructor. */
 LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
@@ -47,7 +48,6 @@ 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(),
-					  mDSOHandlePool());
+					  gAPRPoolp);
 	if(result != APR_SUCCESS)
 	{
 		char buf[1024];
diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h
index 1c3898e2e71..50531ca77f2 100644
--- a/indra/llplugin/llplugininstance.h
+++ b/indra/llplugin/llplugininstance.h
@@ -30,7 +30,6 @@
 
 #include "llstring.h"
 #include "llapr.h"
-#include "llaprpool.h"
 
 #include "apr_dso.h"
 
@@ -89,7 +88,6 @@ class LLPluginInstance
 	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 dd47300b9c6..8d13e38ad5c 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -92,6 +92,8 @@ 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 2fa5dcdd016..45a86476ac3 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(LLSocket::STREAM_TCP);
+	mSocket = LLSocket::create(gAPRPoolp, 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 eaf7ec4bf39..c002de04627 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -33,7 +33,6 @@
 #include "llpluginmessageclasses.h"
 
 #include "llapr.h"
-#include "llscopedvolatileaprpool.h"
 
 //virtual 
 LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
@@ -43,7 +42,6 @@ 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;
@@ -54,7 +52,7 @@ class LLPluginProcessParentPollThread: public LLThread
 {
 public:
 	LLPluginProcessParentPollThread() :
-		LLThread("LLPluginProcessParentPollThread")
+		LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
 	{
 	}
 protected:
@@ -79,11 +77,12 @@ class LLPluginProcessParentPollThread: public LLThread
 
 };
 
-LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner)
+LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
+	mIncomingQueueMutex(gAPRPoolp)
 {
 	if(!sInstancesMutex)
 	{
-		sInstancesMutex = new LLMutex;
+		sInstancesMutex = new LLMutex(gAPRPoolp);
 	}
 	
 	mOwner = owner;
@@ -96,7 +95,6 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner)
 	mBlocked = false;
 	mPolledInput = false;
 	mPollFD.client_data = NULL;
-	mPollFDPool.create();
 
 	mPluginLaunchTimeout = 60.0f;
 	mPluginLockupTimeout = 15.0f;
@@ -171,28 +169,44 @@ 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
 	{
-		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();
-		}
+//		llinfos << "Error:" << llendl;
+		ll_apr_warn_status(status);
+		
+		// Some other error.
+		errorState();
 	}
 	
 	return result;	
@@ -258,10 +272,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(LLSocket::STREAM_TCP);
+				mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
 				mBoundPort = 0;
 				
 				// This code is based on parts of LLSocket::create() in lliosocket.cpp.
@@ -272,7 +286,7 @@ void LLPluginProcessParent::idle(void)
 					APR_INET,
 					0,	// port 0 = ephemeral ("find me a port")
 					0,
-					addr_pool);
+					gAPRPoolp);
 					
 				if(ll_apr_warn_status(status))
 				{
@@ -584,7 +598,7 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
 	if(message_pipe != NULL)
 	{
 		// Set up the apr_pollfd_t
-		mPollFD.p = mPollFDPool();
+		mPollFD.p = gAPRPoolp;
 		mPollFD.desc_type = APR_POLL_SOCKET;
 		mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
 		mPollFD.rtnevents = 0;
@@ -631,7 +645,6 @@ void LLPluginProcessParent::updatePollset()
 		// delete the existing pollset.
 		apr_pollset_destroy(sPollSet);
 		sPollSet = NULL;
-		sPollSetPool.destroy();
 	}
 	
 	std::list<LLPluginProcessParent*>::iterator iter;
@@ -654,14 +667,12 @@ void LLPluginProcessParent::updatePollset()
 		{
 #ifdef APR_POLLSET_NOCOPY
 			// The pollset doesn't exist yet.  Create it now.
-			sPollSetPool.create();
-			apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
+			apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, 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 6beeb64c7ef..32394809ef2 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -176,9 +176,7 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner
 
 	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 e2ff645a9c5..63ff5085c6e 100644
--- a/indra/llplugin/llpluginsharedmemory.cpp
+++ b/indra/llplugin/llpluginsharedmemory.cpp
@@ -187,8 +187,7 @@ bool LLPluginSharedMemory::create(size_t size)
 	mName += createName();
 	mSize = size;
 	
-	mPool.create();
-	apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool());
+	apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
 	
 	if(ll_apr_warn_status(status))
 	{
@@ -211,7 +210,7 @@ bool LLPluginSharedMemory::destroy(void)
 		}
 		mImpl->mAprSharedMemory = NULL;
 	}
-	mPool.destroy();
+	
 	return true;
 }
 
@@ -220,8 +219,7 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
 	mName = name;
 	mSize = size;
 	
-	mPool.create();
-	apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() );
+	apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
 	
 	if(ll_apr_warn_status(status))
 	{
@@ -243,7 +241,6 @@ bool LLPluginSharedMemory::detach(void)
 		}
 		mImpl->mAprSharedMemory = NULL;
 	}
-	mPool.destroy();
 	
 	return true;
 }
diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h
index 84b7a58c328..c6cd49cabb7 100644
--- a/indra/llplugin/llpluginsharedmemory.h
+++ b/indra/llplugin/llpluginsharedmemory.h
@@ -28,8 +28,6 @@
 #ifndef LL_LLPLUGINSHAREDMEMORY_H
 #define LL_LLPLUGINSHAREDMEMORY_H
 
-#include "llaprpool.h"
-
 class LLPluginSharedMemoryPlatformImpl;
 
 /**
@@ -110,7 +108,6 @@ class LLPluginSharedMemory
 	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 ff86e4e1351..516a58db883 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -176,6 +176,8 @@ 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(".");
@@ -391,6 +393,8 @@ 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 bf49b9668e6..3d3ed9f6d4d 100644
--- a/indra/llvfs/lllfsthread.cpp
+++ b/indra/llvfs/lllfsthread.cpp
@@ -67,6 +67,10 @@ LLLFSThread::LLLFSThread(bool threaded) :
 	LLQueuedThread("LFS", threaded),
 	mPriorityCounter(PRIORITY_LOWBITS)
 {
+	if(!mLocalAPRFilePoolp)
+	{
+		mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
+	}
 }
 
 LLLFSThread::~LLLFSThread()
@@ -178,7 +182,8 @@ bool LLLFSThread::Request::processRequest()
 	if (mOperation ==  FILE_READ)
 	{
 		llassert(mOffset >= 0);
-		LLAPRFile infile(mFileName, LL_APR_RB);
+		LLAPRFile infile ; // auto-closes
+		infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool());
 		if (!infile.getFileHandle())
 		{
 			llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
@@ -200,7 +205,8 @@ bool LLLFSThread::Request::processRequest()
 		apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
 		if (mOffset < 0)
 			flags |= APR_APPEND;
-		LLAPRFile outfile(mFileName, flags);
+		LLAPRFile outfile ; // auto-closes
+		outfile.open(mFileName, flags, mThread->getLocalAPRFilePool());
 		if (!outfile.getFileHandle())
 		{
 			llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 1a64623028c..c1fe21c57df 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;
+	mDataMutex = new LLMutex(0);
 
 	S32 i;
 	for (i = 0; i < VFSLOCK_COUNT; i++)
@@ -2094,7 +2094,8 @@ void LLVFS::dumpFiles()
 			std::string filename = id.asString() + extension;
 			llinfos << " Writing " << filename << llendl;
 			
-			LLAPRFile outfile(filename, LL_APR_WB);
+			LLAPRFile outfile;
+			outfile.open(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 77d6d196633..6bc272c009a 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
@@ -37,6 +37,7 @@ 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 93a10424dde..2e4baaa9eb2 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
@@ -28,18 +28,16 @@
 
 #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"
@@ -58,7 +56,7 @@ void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
 }
 
 static bool sSymsGrabbed = false;
-static LLAPRPool sSymGSTDSOMemoryPool;
+static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
 static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
 static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
 
@@ -80,11 +78,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
-	sSymGSTDSOMemoryPool.create();
+	apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
   
 	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"
@@ -98,7 +96,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"
@@ -152,7 +150,8 @@ void ungrab_gst_syms()
 	
 	if ( sSymGSTDSOMemoryPool )
 	{
-		sSymGSTDSOMemoryPool.destroy();
+		apr_pool_destroy(sSymGSTDSOMemoryPool);
+		sSymGSTDSOMemoryPool = NULL;
 	}
 	
 	// 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 94dfd807003..91be3a89e9a 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 LLAPRPool sSymPADSOMemoryPool;
+static apr_pool_t *sSymPADSOMemoryPool = NULL;
 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
-	sSymPADSOMemoryPool.create();
+	apr_pool_create(&sSymPADSOMemoryPool, NULL);
   
 	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,8 +130,12 @@ void ungrab_pa_syms()
 		apr_dso_unload(sSymPADSOHandleG);
 		sSymPADSOHandleG = NULL;
 	}
-
-	sSymPADSOMemoryPool.destroy();
+	
+	if ( sSymPADSOMemoryPool )
+	{
+		apr_pool_destroy(sSymPADSOMemoryPool);
+		sSymPADSOMemoryPool = NULL;
+	}
 	
 	// 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 1f76e2af400..a23f809b712 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;
+	gServicePump = new LLPumpIO(gAPRPoolp);
 	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
-	for(std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> >::iterator plugin = mPlugins.begin();
-		plugin != mPlugins.end(); ++plugin)
+	std::set<struct apr_dso_handle_t *>::const_iterator i;
+	for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
 	{
 		int (*ll_plugin_stop_func)(void) = NULL;
-		apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, plugin->first, "ll_plugin_stop");
+		apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
 		ll_plugin_stop_func();
 
-		rv = apr_dso_unload(plugin->first);
+		rv = apr_dso_unload(*i);
 	}
-	mPlugins.clear();	// Forget handles and destroy all memory pools.
+	mPlugins.clear();
 
 	//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;
+		LLFastTimer::sLogLock = new LLMutex(NULL);
 		mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);
 		mFastTimerLogThread->start();
 	}
@@ -2969,7 +2969,8 @@ 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_name, LL_APR_W);
+		LLAPRFile crash_file ;
+		crash_file.open(crash_file_name, LL_APR_W);
 		if (crash_file.getFileHandle())
 		{
 			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
@@ -3033,10 +3034,11 @@ bool LLAppViewer::anotherInstanceRunning()
 	LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
 
 	//Freeze case checks
-	if (LLAPRFile::isExist(marker_file, LL_APR_RB))
+	if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
 	{
 		// File exists, try opening with write permissions
-		LLAPRFile outfile(marker_file, LL_APR_WB);
+		LLAPRFile outfile ;
+		outfile.open(marker_file, LL_APR_WB);
 		apr_file_t* fMarker = outfile.getFileHandle() ; 
 		if (!fMarker)
 		{
@@ -3075,25 +3077,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, LL_APR_RB) && !anotherInstanceRunning())
+	if (LLAPRFile::isExist(mMarkerFileName, NULL, 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, LL_APR_RB))
+	if(LLAPRFile::isExist(logout_marker_file, NULL, 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, LL_APR_RB))
+	if(LLAPRFile::isExist(llerror_marker_file, NULL, 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, LL_APR_RB))
+	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
 	{
 		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
 		else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
@@ -3109,7 +3111,7 @@ void LLAppViewer::initMarkerFile()
 	
 	// Create the marker file for this execution & lock it
 	apr_status_t s;
-	s = mMarkerFile.open(mMarkerFileName, LL_APR_W, LLAPRFile::long_lived);
+	s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);	
 
 	if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
 	{
@@ -4325,7 +4327,8 @@ void LLAppViewer::sendLogoutRequest()
 		gLogoutInProgress = TRUE;
 		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
 		
-		LLAPRFile outfile(mLogoutMarkerFileName, LL_APR_W);
+		LLAPRFile outfile ;
+		outfile.open(mLogoutMarkerFileName, LL_APR_W);
 		mLogoutMarkerFile =  outfile.getFileHandle() ;
 		if (mLogoutMarkerFile)
 		{
@@ -4775,15 +4778,14 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
 	}
 #endif // LL_WINDOWS
 
-	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;
+	apr_dso_handle_t * eventhost_dso_handle = NULL;
+	apr_pool_t * eventhost_dso_memory_pool = NULL;
 
 	//attempt to load the shared library
-	eventhost_dso_memory_pool.create();
+	apr_pool_create(&eventhost_dso_memory_pool, NULL);
 	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);
 
@@ -4803,8 +4805,7 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
 		llerrs << "problem loading eventhost plugin, status: " << status << llendl;
 	}
 
-	// Store the handle and link it to the pool that was used to allocate it.
-	mPlugins[eventhost_dso_handle] = eventhost_dso_memory_pool_ptr;
+	mPlugins.insert(eventhost_dso_handle);
 }
 
 void LLAppViewer::launchUpdater()
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 00b12d50aed..a18e6cbb028 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -266,7 +266,7 @@ class LLAppViewer : public LLApp
 
     LLAllocator mAlloc;
 
-	std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> > mPlugins;
+	std::set<struct apr_dso_handle_t*> mPlugins;
 
 	U32 mAvailPhysicalMemInKB ;
 	U32 mAvailVirtualMemInKB ;
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index d4c6131c803..898cc1c0ba8 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -110,7 +110,6 @@ 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 1ae469dfcfd..32e7e0a83d5 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 LLAPRPool sSymDBUSDSOMemoryPool;
+static apr_pool_t *sSymDBUSDSOMemoryPool = NULL;
 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
-	sSymDBUSDSOMemoryPool.create();
+	apr_pool_create(&sSymDBUSDSOMemoryPool, NULL);
   
 	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,7 +109,11 @@ void ungrab_dbus_syms()
 		sSymDBUSDSOHandleG = NULL;
 	}
 	
-	sSymDBUSDSOMemoryPool.destroy();
+	if ( sSymDBUSDSOMemoryPool )
+	{
+		apr_pool_destroy(sSymDBUSDSOMemoryPool);
+		sSymDBUSDSOMemoryPool = NULL;
+	}
 	
 	// 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 13c8745eaff..1cd80986d8c 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -113,7 +113,6 @@ 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 9b96332c100..deebd69ec10 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -223,7 +223,8 @@ BOOL LLFloaterAnimPreview::postBuild()
 		// now load bvh file
 		S32 file_size;
 		
-		LLAPRFile infile(mFilenameAndPath, LL_APR_RB, &file_size);
+		LLAPRFile infile ;
+		infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size);
 		
 		if (!infile.getFileHandle())
 		{
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index d73048a28b1..5c020e6d982 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>(1024);
+	mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 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 a47ea8581a9..f54214b95cb 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -176,7 +176,7 @@ class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
 
 bool LLTextureCacheLocalFileWorker::doRead()
 {
-	S32 local_size = LLAPRFile::size(mFileName);
+	S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
 
 	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);
+	S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());	
 
 	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);
+			local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
 			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);
+			local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
 			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);
+			local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
 			if (local_size > 0)
 			{
 				mImageFormat = IMG_CODEC_TGA;
@@ -378,7 +378,8 @@ bool LLTextureCacheRemoteWorker::doRead()
 		}
 		// Allocate read buffer
 		mReadData = new U8[mDataSize];
-		S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize);
+		S32 bytes_read = LLAPRFile::readEx(local_filename, 
+											 mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
 		if (bytes_read != mDataSize)
 		{
  			llwarns << "Error reading file from local cache: " << local_filename
@@ -429,7 +430,8 @@ 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);
+		S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, 
+											 mReadData, offset, size, mCache->getLocalAPRFilePool());
 		if (bytes_read != size)
 		{
 			llwarns << "LLTextureCacheWorker: "  << mID
@@ -455,7 +457,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 	if (!done && (mState == BODY))
 	{
 		std::string filename = mCache->getTextureFileName(mID);
-		S32 filesize = LLAPRFile::size(filename);
+		S32 filesize = LLAPRFile::size(filename, mCache->getLocalAPRFilePool());
 
 		if (filesize && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset)
 		{
@@ -497,7 +499,8 @@ bool LLTextureCacheRemoteWorker::doRead()
 			// Read the data at last
 			S32 bytes_read = LLAPRFile::readEx(filename, 
 											 mReadData + data_offset,
-											 file_offset, file_size);
+											 file_offset, file_size,
+											 mCache->getLocalAPRFilePool());
 			if (bytes_read != file_size)
 			{
 				llwarns << "LLTextureCacheWorker: "  << mID
@@ -598,13 +601,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);
+			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
 			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);
+			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
 		}
 
 		if (bytes_written <= 0)
@@ -639,7 +642,8 @@ 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);
+													0, file_size,
+													mCache->getLocalAPRFilePool());
 			if (bytes_written <= 0)
 			{
 				llwarns << "LLTextureCacheWorker: "  << mID
@@ -736,6 +740,9 @@ 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),
@@ -839,7 +846,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
 	// Is it a JPEG2000 file? 
 	{
 		local_filename = filename + ".j2c";
-		local_size = LLAPRFile::size(local_filename);
+		local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
 		if (local_size > 0)
 		{
 			return TRUE ;
@@ -849,7 +856,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
 	// If not, is it a jpeg file?		
 	{
 		local_filename = filename + ".jpg";
-		local_size = LLAPRFile::size(local_filename);
+		local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
 		if (local_size > 0)
 		{
 			return TRUE ;
@@ -859,7 +866,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);
+		local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
 		if (local_size > 0)
 		{
 			return TRUE ;
@@ -905,10 +912,10 @@ void LLTextureCache::purgeCache(ELLPath location)
 		if(LLFile::isdir(mTexturesDirName))
 		{
 			std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
-			LLAPRFile::remove(file_name);
+			LLAPRFile::remove(file_name, getLocalAPRFilePool());
 
 			file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
-			LLAPRFile::remove(file_name);
+			LLAPRFile::remove(file_name, getLocalAPRFilePool());
 
 			purgeAllTextures(true);
 		}
@@ -984,9 +991,7 @@ 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;
-	// All code calling openHeaderEntriesFile, immediately calls closeHeaderEntriesFile,
-	// so this file is very short-lived.
-	mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags);
+	mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
 	if(offset > 0)
 	{
 		mHeaderAPRFile->seek(APR_SET, offset);
@@ -1009,9 +1014,10 @@ void LLTextureCache::readEntriesHeader()
 {
 	// mHeaderEntriesInfo initializes to default values so safe not to read it
 	llassert_always(mHeaderAPRFile == NULL);
-	if (LLAPRFile::isExist(mHeaderEntriesFileName))
+	if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
 	{
-		LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
+		LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
+						  getLocalAPRFilePool());
 	}
 	else //create an empty entries header.
 	{
@@ -1026,7 +1032,8 @@ void LLTextureCache::writeEntriesHeader()
 	llassert_always(mHeaderAPRFile == NULL);
 	if (!mReadOnly)
 	{
-		LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
+		LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
+						   getLocalAPRFilePool());
 	}
 }
 
@@ -1616,7 +1623,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);
+				S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
 				if (bodysize != entries[idx].mBodySize)
 				{
 					LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
@@ -1851,7 +1858,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
 		mTexturesSizeMap.erase(id);
 	}
 	mHeaderIDMap.erase(id);
-	LLAPRFile::remove(getTextureFileName(id));		
+	LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());		
 }
 
 //called after mHeaderMutex is locked.
@@ -1863,7 +1870,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))		// Sanity check. Shouldn't exist when body size is 0.
+		  if (LLAPRFile::isExist(filename, getLocalAPRFilePool()))		// 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;
 		  }
@@ -1884,7 +1891,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
 
 	if (file_maybe_exists)
 	{
-		LLAPRFile::remove(filename);
+		LLAPRFile::remove(filename, getLocalAPRFilePool());		
 	}
 }
 
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 79f5ba58358..64e3a2658c3 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -142,6 +142,9 @@ class LLTextureCache : public LLWorkerThread
 	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 139b434aeb4..18c3a3b87dd 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -674,6 +674,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mRetryAttempt(0),
 	  mActiveCount(0),
 	  mGetStatus(0),
+	  mWorkMutex(NULL),
 	  mFirstPacket(0),
 	  mLastPacket(-1),
 	  mTotalPackets(0),
@@ -1815,6 +1816,8 @@ 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 6bee7556cd1..fda291f3c1c 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -736,7 +736,8 @@ 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(filename, LL_APR_RB, &file_size);
+		LLAPRFile infile ;
+		infile.open(filename, LL_APR_RB, NULL, &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 2cd9b099324..fd89044995a 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7190,7 +7190,8 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 // static
 void LLVOAvatar::dumpArchetypeXML( void* )
 {
-	LLAPRFile outfile(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER, "new archetype.xml"), LL_APR_WB);
+	LLAPRFile outfile;
+	outfile.open(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 d25831b4f11..a9335007062 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -30,14 +30,14 @@
 #include "llregionhandle.h"
 #include "llviewercontrol.h"
 
-static BOOL check_read(LLAPRFile& apr_file, void* src, S32 n_bytes) 
+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 ;
 }
 
-static BOOL check_write(LLAPRFile& apr_file, void* src, S32 n_bytes) 
+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,6 +266,7 @@ LLVOCache::LLVOCache():
 	mCacheSize(1)
 {
 	mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
+	mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
 }
 
 LLVOCache::~LLVOCache()
@@ -275,6 +276,7 @@ LLVOCache::~LLVOCache()
 		writeCacheHeader();
 		clearCacheInMemory();
 	}
+	delete mLocalAPRFilePoolp;
 }
 
 void LLVOCache::setDirNames(ELLPath location)
@@ -435,7 +437,7 @@ void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
 
 	std::string filename;
 	getObjectCacheFilename(entry->mHandle, filename);
-	LLAPRFile::remove(filename);
+	LLAPRFile::remove(filename, mLocalAPRFilePoolp);
 	entry->mTime = INVALID_TIME ;
 	updateEntry(entry) ; //update the head file.
 }
@@ -452,12 +454,12 @@ void LLVOCache::readCacheHeader()
 	clearCacheInMemory();	
 
 	bool success = true ;
-	if (LLAPRFile::isExist(mHeaderFileName))
+	if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
 	{
-		LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY);		
+		LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);		
 		
 		//read the meta element
-		success = check_read(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
+		success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
 		
 		if(success)
 		{
@@ -470,7 +472,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
 				{
@@ -539,17 +541,17 @@ void LLVOCache::writeCacheHeader()
 
 	bool success = true ;
 	{
-		LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY);
+		LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
 
 		//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() ;
@@ -560,7 +562,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 ;
@@ -577,10 +579,10 @@ void LLVOCache::writeCacheHeader()
 
 BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
 {
-	LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY);
-	apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo));
+	LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+	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) 
@@ -603,10 +605,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);
+		LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
 	
 		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)
 		{		
@@ -619,11 +621,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;
@@ -722,19 +724,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);
+		LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
 	
-		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 76456b9e987..14e3b4c7935 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 @@ class LLVOCacheEntry
 	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,6 +142,7 @@ class LLVOCache
 	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 828207ce1ab..08e242af8eb 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -961,7 +961,7 @@ void LLVivoxVoiceClient::stateMachine()
 
 				if(!mSocket)
 				{
-					mSocket = LLSocket::create(LLSocket::STREAM_TCP);	
+					mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);	
 				}
 				
 				mConnected = mSocket->blockingConnect(mDaemonHost);
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index d982ca50200..16941268028 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;
-		mTimer = new LLWatchdogTimerThread;
+		mSuspectsAccessMutex = new LLMutex(NULL);
+		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 102294959a3..acc6e814bc7 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -27,6 +27,7 @@
 
 // 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 532f26ee608..09beb53869d 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -29,6 +29,7 @@
 #include "linden_common.h"
 #include "lltut.h"
 
+#include "llapr.h"
 #include "llmessagetemplate.h"
 #include "llquaternion.h"
 #include "lltemplatemessagebuilder.h"
@@ -52,6 +53,7 @@ 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 9a6ccd4d681..d971b334752 100644
--- a/indra/test/message_tut.cpp
+++ b/indra/test/message_tut.cpp
@@ -29,6 +29,7 @@
 #include "linden_common.h"
 #include "lltut.h"
 
+#include "llapr.h"
 #include "llmessageconfig.h"
 #include "llsdserialize.h"
 #include "llversionserver.h"
@@ -61,6 +62,7 @@ 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 45e8aef99a9..ffdb0cb976a 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,12 +349,17 @@ int main(int argc, char **argv)
 	ctype_workaround();
 #endif
 
-	LLAPRPool pool;
-	pool.create();
+	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;
+	}
 	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 initialize the arguments for parsing by apr_getopt()." << std::endl;
+		std::cerr << "Unable to  pool" << std::endl;
 		return 1;
 	}
 
@@ -472,6 +477,8 @@ 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 fd46626ff11..4a2272032b0 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -27,6 +27,7 @@
 #include "linden_common.h"
 #include "indra_constants.h"
 
+#include "llapr.h"
 #include "llerrorcontrol.h"
 
 #include <math.h>
@@ -185,6 +186,9 @@ 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 6aa87d1be6e..d450c068ade 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -26,7 +26,6 @@
 #include "linden_common.h"
 #include <apr_file_io.h>
 #include "llapr.h"
-#include "llscopedvolatileaprpool.h"
 #include "llprocesslauncher.h"
 #include "llupdateinstaller.h"
 #include "lldir.h"
@@ -46,8 +45,7 @@ namespace {
 	{
 		std::string scriptFile = gDirUtilp->getBaseFileName(path);
 		std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile);
-		LLScopedVolatileAPRPool pool;
-		apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, pool);
+		apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp);
 		if(status != APR_SUCCESS) throw RelocateError();
 		
 		return newPath;
-- 
GitLab