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