diff options
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llapr.cpp | 161 | ||||
| -rw-r--r-- | indra/llcommon/llapr.h | 34 | ||||
| -rw-r--r-- | indra/llcommon/llqueuedthread.cpp | 70 | ||||
| -rw-r--r-- | indra/llcommon/llqueuedthread.h | 4 | ||||
| -rw-r--r-- | indra/llcommon/llthread.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llworkerthread.cpp | 1 | ||||
| -rw-r--r-- | indra/llcommon/llworkerthread.h | 6 | 
7 files changed, 184 insertions, 94 deletions
| diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 669afc5330..ed70b1d9f2 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -57,7 +57,7 @@ void ll_init_apr()  	if(!LLAPRFile::sAPRFilePoolp)  	{ -		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool() ; +		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;  	}  } @@ -99,13 +99,12 @@ void ll_cleanup_apr()  //  //LLAPRPool  // -LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)  -{ -	mParent = parent ; -	mReleasePoolFlag = releasePoolFlag ; -	mMaxSize = size ; -	mPool = NULL ; - +LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) 	 +	: mParent(parent), +	mReleasePoolFlag(releasePoolFlag), +	mMaxSize(size), +	mPool(NULL) +{	  	createAPRPool() ;  } @@ -148,31 +147,65 @@ void LLAPRPool::releaseAPRPool()  	}  } +//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)  { -	if(!mPool) +	//create mutex +	if(!is_local) //not a local apr_pool, that is: shared by multiple threads.  	{ -		createAPRPool() ; +		apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex +		apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);  	} -	 -	return mPool ;   } -LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)  -				  : LLAPRPool(parent, size, releasePoolFlag) + +LLVolatileAPRPool::~LLVolatileAPRPool()  { -	mNumActiveRef = 0 ; -	mNumTotalRef = 0 ; +	//delete mutex +	if(mMutexp) +	{ +		apr_thread_mutex_destroy(mMutexp); +		apr_pool_destroy(mMutexPool); +	}  } -apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()  +// +//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++ ; -	return getAPRPool() ; + +	if(!mPool) +	{ +		createAPRPool() ; +	} +	 +	return mPool ;  }  void LLVolatileAPRPool::clearVolatileAPRPool()   { +	LLScopedLock lock(mMutexp) ; +  	if(mNumActiveRef > 0)  	{  		mNumActiveRef--; @@ -251,10 +284,9 @@ void LLScopedLock::unlock()  bool ll_apr_warn_status(apr_status_t status)  {  	if(APR_SUCCESS == status) return false; -#ifndef LL_WINDOWS  	char buf[MAX_STRING];	/* Flawfinder: ignore */ -	LL_WARNS_ONCE("APR") << "APR: " << apr_strerror(status, buf, MAX_STRING) << LL_ENDL; -#endif +	apr_strerror(status, buf, MAX_STRING); +	LL_WARNS("APR") << "APR: " << buf << LL_ENDL;  	return true;  } @@ -268,10 +300,18 @@ void ll_apr_assert_status(apr_status_t status)  // LLAPRFile functions  //  LLAPRFile::LLAPRFile() +	: mFile(NULL), +	  mCurrentFilePoolp(NULL) +{ +} + +LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool) +	: mFile(NULL), +	  mCurrentFilePoolp(NULL)  { -	mFile = NULL ; -	mCurrentFilePoolp = NULL ; +	open(filename, flags, pool);  } +  LLAPRFile::~LLAPRFile()  {  	close() ; @@ -295,11 +335,40 @@ apr_status_t LLAPRFile::close()  	return ret ;  } -apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep) +apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep)  {  	apr_status_t s ; -	s = open(filename, flags, pool ? pool->getVolatileAPRPool() : NULL, sizep) ; + +	//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 ; +		 +		if (sizep) +		{ +			*sizep = 0; +		} +	} +	else if (sizep) +	{ +		S32 file_size = 0; +		apr_off_t offset = 0; +		if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS) +		{ +			llassert_always(offset <= 0x7fffffff); +			file_size = (S32)offset; +			offset = 0; +			apr_file_seek(mFile, APR_SET, &offset); +		} +		*sizep = file_size; +	} +  	if(!mCurrentFilePoolp)  	{  		mCurrentFilePoolp = pool ; @@ -312,40 +381,25 @@ apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filenam  	return s ;  } -apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool, S32* sizep) + +//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, getAPRFilePool(pool)); +	s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp);  	if (s != APR_SUCCESS || !mFile)  	{  		mFile = NULL ;  		close() ; -		if (sizep) -		{ -			*sizep = 0; -		}  		return s;  	} -	if (sizep) -	{ -		S32 file_size = 0; -		apr_off_t offset = 0; -		if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS) -		{ -			llassert_always(offset <= 0x7fffffff); -			file_size = (S32)offset; -			offset = 0; -			apr_file_seek(mFile, APR_SET, &offset); -		} -		*sizep = file_size; -	} -  	return s;  } @@ -369,6 +423,7 @@ S32 LLAPRFile::read(void *buf, S32 nbytes)  	apr_status_t s = apr_file_read(mFile, buf, &sz);  	if (s != APR_SUCCESS)  	{ +		ll_apr_warn_status(s);  		return 0;  	}  	else @@ -386,6 +441,7 @@ S32 LLAPRFile::write(const void *buf, S32 nbytes)  	apr_status_t s = apr_file_write(mFile, buf, &sz);  	if (s != APR_SUCCESS)  	{ +		ll_apr_warn_status(s);  		return 0;  	}  	else @@ -434,6 +490,8 @@ apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool  	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; @@ -464,6 +522,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)  	}  	if (s != APR_SUCCESS)  	{ +		ll_apr_warn_status(s);  		return -1;  	}  	else @@ -501,6 +560,8 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb  		apr_status_t s = apr_file_read(file_handle, buf, &bytes_read);  		if (s != APR_SUCCESS)  		{ +			LL_WARNS("APR") << " Attempting to read filename: " << filename << LL_ENDL; +			ll_apr_warn_status(s);  			bytes_read = 0;  		}  		else @@ -549,6 +610,8 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n  		apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);  		if (s != APR_SUCCESS)  		{ +			LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL; +			ll_apr_warn_status(s);  			bytes_written = 0;  		}  		else @@ -575,8 +638,8 @@ bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)  	if (s != APR_SUCCESS)  	{ -		LL_DEBUGS("APR") << "LLAPRFile::remove failed on file: " << filename << LL_ENDL;  		ll_apr_warn_status(s); +		LL_WARNS("APR") << " Attempting to remove filename: " << filename << LL_ENDL;  		return false;  	}  	return true; @@ -593,8 +656,8 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname,  	if (s != APR_SUCCESS)  	{ -		LL_DEBUGS("APR") << "LLAPRFile::rename failed on file: " << filename << LL_ENDL;  		ll_apr_warn_status(s); +		LL_WARNS("APR") << " Attempting to rename filename: " << filename << LL_ENDL;  		return false;  	}  	return true; @@ -667,8 +730,8 @@ bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)  	if (s != APR_SUCCESS)  	{ -		LL_DEBUGS("APR") << "LLAPRFile::makeDir failed on file: " << dirname << LL_ENDL;  		ll_apr_warn_status(s); +		LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;  		return false;  	}  	return true; @@ -685,8 +748,8 @@ bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)  	if (s != APR_SUCCESS)  	{ -		LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL;  		ll_apr_warn_status(s); +		LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL;  		return false;  	}  	return true; diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 63130a89fc..a1a4c6db4a 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -70,9 +70,9 @@ class LLAPRPool  {  public:  	LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; -	~LLAPRPool() ; +	virtual ~LLAPRPool() ; -	apr_pool_t* getAPRPool() ; +	virtual apr_pool_t* getAPRPool() ;  	apr_status_t getStatus() {return mStatus ; }  protected: @@ -95,18 +95,21 @@ protected:  class LLVolatileAPRPool : public LLAPRPool  {  public: -	LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); -	~LLVolatileAPRPool(){} +	LLVolatileAPRPool(BOOL is_local = TRUE, apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); +	virtual ~LLVolatileAPRPool(); -	apr_pool_t* getVolatileAPRPool() ; -	 +	/*virtual*/ apr_pool_t* getAPRPool() ; //define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool(). +	apr_pool_t* getVolatileAPRPool() ;	  	void        clearVolatileAPRPool() ;  	BOOL        isFull() ; -	BOOL        isEmpty() {return !mNumActiveRef ;} +	  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.    +	S32 mNumTotalRef ;  //number of total pointers pointing to the apr_pool since last creating.   + +	apr_thread_mutex_t *mMutexp; +	apr_pool_t         *mMutexPool;  } ;  /**  @@ -192,18 +195,21 @@ typedef LLAtomic32<S32> LLAtomicS32;  //      1, a temperary pool passed to an APRFile function, which is used within this function and only once.  //      2, a global pool.  // -class LLAPRFile + +class LLAPRFile : boost::noncopyable  { +	// make this non copyable since a copy closes the file  private:  	apr_file_t* mFile ;  	LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.   public:  	LLAPRFile() ; +	LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL);  	~LLAPRFile() ; - -	apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL); -	apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, 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 @@ -217,8 +223,8 @@ public:  	apr_file_t* getFileHandle() {return mFile;}	  private: -	apr_pool_t* getAPRFilePool(apr_pool_t* pool) ; - +	apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;	 +	  //  //*******************************************************************************************************************************  //static components diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 3db5c36545..395d298887 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -42,7 +42,8 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded) :  	LLThread(name),  	mThreaded(threaded),  	mIdleThread(TRUE), -	mNextHandle(0) +	mNextHandle(0), +	mStarted(FALSE)  {  	if (mThreaded)  	{ @@ -53,6 +54,10 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded) :  // MAIN THREAD  LLQueuedThread::~LLQueuedThread()  { +	if (!mThreaded) +	{ +		endThread(); +	}  	shutdown();  	// ~LLThread() will be called here  } @@ -106,6 +111,11 @@ void LLQueuedThread::shutdown()  // virtual  S32 LLQueuedThread::update(U32 max_time_ms)  { +	if (!mStarted) +	{ +		startThread(); +		mStarted = TRUE; +	}  	return updateQueue(max_time_ms);  } @@ -452,26 +462,12 @@ S32 LLQueuedThread::processNextRequest()  		}  	} -	S32 res;  	S32 pending = getPending(); -	if (pending == 0) -	{ -		if (isQuitting()) -		{ -			res = -1; // exit thread -		} -		else -		{ -			res = 0; -		} -	} -	else -	{ -		res = pending; -	} -	return res; + +	return pending;  } +// virtual  bool LLQueuedThread::runCondition()  {  	// mRunCondition must be locked here @@ -481,35 +477,53 @@ bool LLQueuedThread::runCondition()  		return true;  } +// virtual  void LLQueuedThread::run()  { +	// call checPause() immediately so we don't try to do anything before the class is fully constructed +	checkPause(); +	startThread(); +	mStarted = TRUE; +	  	while (1)  	{  		// this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state.  		checkPause(); -		if(isQuitting()) +		if (isQuitting()) +		{ +			endThread();  			break; - -		//llinfos << "QUEUED THREAD RUNNING, queue size = " << mRequestQueue.size() << llendl; +		}  		mIdleThread = FALSE; + +		threadedUpdate();  		int res = processNextRequest();  		if (res == 0)  		{  			mIdleThread = TRUE; +			ms_sleep(1);  		} -		 -		if (res < 0) // finished working and want to exit -		{ -			break; -		} -  		//LLThread::yield(); // thread should yield after each request		  	} +	llinfos << "LLQueuedThread " << mName << " EXITING." << llendl; +} -	llinfos << "QUEUED THREAD " << mName << " EXITING." << llendl; +// virtual +void LLQueuedThread::startThread() +{ +} + +// virtual +void LLQueuedThread::endThread() +{ +} + +// virtual +void LLQueuedThread::threadedUpdate() +{  }  //============================================================================ diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 3ba43e1e07..bcd154da0b 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -165,6 +165,9 @@ private:  	virtual bool runCondition(void);  	virtual void run(void); +	virtual void startThread(void); +	virtual void endThread(void); +	virtual void threadedUpdate(void);  protected:  	handle_t generateHandle(); @@ -199,6 +202,7 @@ public:  protected:  	BOOL mThreaded;  // if false, run on main thread and do updates during update() +	BOOL mStarted;  // required when mThreaded is false to call startThread() from update()  	LLAtomic32<BOOL> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle  	typedef std::set<QueuedRequest*, queued_request_less> request_queue_t; diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index f25339f48d..1470dca14c 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -33,9 +33,7 @@  #ifndef LL_LLTHREAD_H  #define LL_LLTHREAD_H -#include "llapr.h"  #include "llapp.h" -  #include "apr_thread_cond.h"  class LLThread; diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 5dda600755..82c736266d 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -201,6 +201,7 @@ LLWorkerClass::~LLWorkerClass()  {  	llassert_always(!(mWorkFlags & WCF_WORKING));  	llassert_always(mWorkFlags & WCF_DELETE_REQUESTED); +	llassert_always(!mMutex.isLocked());  	if (mRequestHandle != LLWorkerThread::nullHandle())  	{  		LLWorkerThread::WorkRequest* workreq = (LLWorkerThread::WorkRequest*)mWorkerThread->getRequest(mRequestHandle); diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 19407f4463..4a4cd6c85f 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -52,6 +52,7 @@ class LLWorkerClass;  class LLWorkerThread : public LLQueuedThread  { +	friend class LLWorkerClass;  public:  	class WorkRequest : public LLQueuedThread::QueuedRequest  	{ @@ -92,8 +93,11 @@ public:  	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); -	void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion  	S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug + +private: +	void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion +	  };  //============================================================================ | 
