Scott Lawrence avatar Scott Lawrence committed 65a2c1c Merge

merge changes for vmrg-210

Comments (0)

Files changed (3)

indra/llcommon/llthread.h

 	LLMutexLock(LLMutex* mutex)
 	{
 		mMutex = mutex;
-		mMutex->lock();
+		
+		if(mMutex)
+			mMutex->lock();
 	}
 	~LLMutexLock()
 	{
-		mMutex->unlock();
+		if(mMutex)
+			mMutex->unlock();
 	}
 private:
 	LLMutex* mMutex;

indra/llmessage/llcurl.cpp

 
 std::set<CURL*> LLCurl::Easy::sFreeHandles;
 std::set<CURL*> LLCurl::Easy::sActiveHandles;
+LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
 
 //static
 CURL* LLCurl::Easy::allocEasyHandle()
 {
 	CURL* ret = NULL;
+
+	LLMutexLock lock(sHandleMutexp) ;
+
 	if (sFreeHandles.empty())
 	{
 		ret = curl_easy_init();
 		llerrs << "handle cannot be NULL!" << llendl;
 	}
 
+	LLMutexLock lock(sHandleMutexp) ;
 	if (sActiveHandles.find(handle) != sActiveHandles.end())
 	{
 		sActiveHandles.erase(handle);
 }
 
 ////////////////////////////////////////////////////////////////////////////
-
+LLMutex* LLCurl::Multi::sMultiInitMutexp = NULL ;
 LLCurl::Multi::Multi()
 	: mQueued(0),
 	  mErrorCount(0),
 	  mState(STATE_READY),
 	  mDead(FALSE),
 	  mMutexp(NULL),
-	  mDeletionMutexp(NULL)
+	  mDeletionMutexp(NULL),
+	  mEasyMutexp(NULL)
 {
-	mCurlMultiHandle = curl_multi_init();
+	mCurlMultiHandle = initMulti();
 	if (!mCurlMultiHandle)
 	{
 		llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
-		mCurlMultiHandle = curl_multi_init();
+		mCurlMultiHandle = initMulti();
 	}
 	
 	llassert_always(mCurlMultiHandle);	
 	{
 		mMutexp = new LLMutex(NULL) ;
 		mDeletionMutexp = new LLMutex(NULL) ;
+		mEasyMutexp = new LLMutex(NULL) ;
 	}
 	LLCurl::getCurlThread()->addMulti(this) ;
 
 	mMutexp = NULL ;
 	delete mDeletionMutexp ;
 	mDeletionMutexp = NULL ;
+	delete mEasyMutexp ;
+	mEasyMutexp = NULL ;
 
 	--gCurlMultiCount;
 }
 
+CURLM* LLCurl::Multi::initMulti()
+{
+	LLMutexLock lock(sMultiInitMutexp) ;
+
+	return curl_multi_init() ;
+}
+
 void LLCurl::Multi::lock()
 {
 	if(mMutexp)
 
 void LLCurl::Multi::markDead()
 {
-	if(mDeletionMutexp)
-	{
-		mDeletionMutexp->lock() ;
-	}
-
+	LLMutexLock lock(mDeletionMutexp) ;
+	
 	mDead = TRUE ;
-
-	if(mDeletionMutexp)
-	{
-		mDeletionMutexp->unlock() ;
-	}
 }
 
 void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
 {
 	lock() ;
 	mState = state ;
+	unlock() ;
+
 	if(mState == STATE_READY)
 	{
 		LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL) ;
-	}
-	unlock() ;
+	}	
 }
 
 LLCurl::Multi::ePerformState LLCurl::Multi::getState()
 {
-	ePerformState state ;
-
-	lock() ;
-	state = mState ;
-	unlock() ;
-
-	return state ;
+	return mState;
 }
 	
 bool LLCurl::Multi::isCompleted() 
 		return true ;
 	}
 
-	bool completed ;
-
-	lock() ;
-	completed = (STATE_COMPLETED == mState) ;
+	bool completed = (STATE_COMPLETED == mState) ;
 	if(!completed)
 	{
 		LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
 	}
-	unlock() ;
-
+	
 	return completed;
 }
 
 CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
 {
+	LLMutexLock lock(mMutexp) ;
+
 	CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue);
 	return curlmsg;
 }
 //return true if dead
 bool LLCurl::Multi::doPerform()
 {
-	if(mDeletionMutexp)
-	{
-		mDeletionMutexp->lock() ;
-	}
+	LLMutexLock lock(mDeletionMutexp) ;
+	
 	bool dead = mDead ;
 
 	if(mDead)
 				call_count < MULTI_PERFORM_CALL_REPEAT;
 				call_count++)
 		{
+			LLMutexLock lock(mMutexp) ;
 			CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
 			if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
 			{
 		setState(STATE_COMPLETED) ;
 	}
 
-	if(mDeletionMutexp)
-	{
-		mDeletionMutexp->unlock() ;
-	}
-
 	return dead ;
 }
 
 		if (msg->msg == CURLMSG_DONE)
 		{
 			U32 response = 0;
-			easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle);
-			if (iter != mEasyActiveMap.end())
+			Easy* easy = NULL ;
+
 			{
-				Easy* easy = iter->second;
+				LLMutexLock lock(mEasyMutexp) ;
+				easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle);
+				if (iter != mEasyActiveMap.end())
+				{
+					easy = iter->second;
+				}
+			}
+
+			if(easy)
+			{
 				response = easy->report(msg->data.result);
 				removeEasy(easy);
 			}
 
 LLCurl::Easy* LLCurl::Multi::allocEasy()
 {
-	Easy* easy = 0;
+	Easy* easy = 0;	
 
 	if (mEasyFreeList.empty())
-	{
+	{		
 		easy = Easy::getEasy();
 	}
 	else
 	{
+		LLMutexLock lock(mEasyMutexp) ;
 		easy = *(mEasyFreeList.begin());
 		mEasyFreeList.erase(easy);
 	}
 	if (easy)
 	{
+		LLMutexLock lock(mEasyMutexp) ;
 		mEasyActiveList.insert(easy);
 		mEasyActiveMap[easy->getCurlHandle()] = easy;
 	}
 
 bool LLCurl::Multi::addEasy(Easy* easy)
 {
+	LLMutexLock lock(mMutexp) ;
 	CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle());
 	check_curl_multi_code(mcode);
 	//if (mcode != CURLM_OK)
 
 void LLCurl::Multi::easyFree(Easy* easy)
 {
+	if(mEasyMutexp)
+	{
+		mEasyMutexp->lock() ;
+	}
+
 	mEasyActiveList.erase(easy);
 	mEasyActiveMap.erase(easy->getCurlHandle());
+
 	if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE)
-	{
+	{		
+		mEasyFreeList.insert(easy);
+		
+		if(mEasyMutexp)
+		{
+			mEasyMutexp->unlock() ;
+		}
+
 		easy->resetState();
-		mEasyFreeList.insert(easy);
 	}
 	else
 	{
+		if(mEasyMutexp)
+		{
+			mEasyMutexp->unlock() ;
+		}
 		delete easy;
 	}
 }
 
 void LLCurl::Multi::removeEasy(Easy* easy)
 {
-	check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+	{
+		LLMutexLock lock(mMutexp) ;
+		check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+	}
 	easyFree(easy);
 }
 
 LLCurlThread::LLCurlThread(bool threaded) :
 	LLQueuedThread("curlthread", threaded)
 {
+	if(!LLCurl::Multi::sMultiInitMutexp)
+	{
+		LLCurl::Multi::sMultiInitMutexp = new LLMutex(NULL) ;
+	}
 }
 	
 //virtual 
 LLCurlThread::~LLCurlThread() 
 {
+	delete LLCurl::Multi::sMultiInitMutexp ;
+	LLCurl::Multi::sMultiInitMutexp = NULL ;
 }
 
 S32 LLCurlThread::update(U32 max_time_ms)
 #endif
 
 	sCurlThread = new LLCurlThread(multi_threaded) ;
+	if(multi_threaded)
+	{
+		Easy::sHandleMutexp = new LLMutex(NULL) ;
+	}
 }
 
 void LLCurl::cleanupClass()
 
 	Easy::sFreeHandles.clear();
 
+	delete Easy::sHandleMutexp ;
+	Easy::sHandleMutexp = NULL ;
+
 	llassert(Easy::sActiveHandles.empty());
 }
 

indra/llmessage/llcurl.h

 
 	static std::set<CURL*> sFreeHandles;
 	static std::set<CURL*> sActiveHandles;
+	static LLMutex*        sHandleMutexp ;
 };
 
 class LLCurl::Multi
 	S32 mQueued;
 	S32 mErrorCount;
 	
+	static CURLM* initMulti() ;
 private:
 	void easyFree(LLCurl::Easy*);
 	
 	BOOL mDead ;
 	LLMutex* mMutexp ;
 	LLMutex* mDeletionMutexp ;
+	LLMutex* mEasyMutexp ;
+
+	static LLMutex* sMultiInitMutexp ;
 };
 
 class LLCurlThread : public LLQueuedThread
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.