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