diff options
| -rw-r--r-- | indra/llcommon/llthread.h | 7 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.cpp | 131 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.h | 5 | ||||
| -rw-r--r-- | indra/newview/llchiclet.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llscriptfloater.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llsyswellwindow.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llsyswellwindow.h | 1 | 
7 files changed, 123 insertions, 51 deletions
| diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 40291a2569..f0e0de6173 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -187,11 +187,14 @@ public:  	LLMutexLock(LLMutex* mutex)  	{  		mMutex = mutex; -		mMutex->lock(); +		 +		if(mMutex) +			mMutex->lock();  	}  	~LLMutexLock()  	{ -		mMutex->unlock(); +		if(mMutex) +			mMutex->unlock();  	}  private:  	LLMutex* mMutex; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7ca25d07fc..f569630766 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -219,11 +219,15 @@ namespace boost  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(); @@ -251,6 +255,7 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)  		llerrs << "handle cannot be NULL!" << llendl;  	} +	LLMutexLock lock(sHandleMutexp) ;  	if (sActiveHandles.find(handle) != sActiveHandles.end())  	{  		sActiveHandles.erase(handle); @@ -512,20 +517,21 @@ void LLCurl::Easy::prepRequest(const std::string& url,  }  //////////////////////////////////////////////////////////////////////////// - +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);	 @@ -534,6 +540,7 @@ LLCurl::Multi::Multi()  	{  		mMutexp = new LLMutex(NULL) ;  		mDeletionMutexp = new LLMutex(NULL) ; +		mEasyMutexp = new LLMutex(NULL) ;  	}  	LLCurl::getCurlThread()->addMulti(this) ; @@ -563,10 +570,19 @@ LLCurl::Multi::~Multi()  	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) @@ -585,39 +601,26 @@ void LLCurl::Multi::unlock()  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()  @@ -633,21 +636,19 @@ bool LLCurl::Multi::waitToComplete()  		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;  } @@ -655,10 +656,8 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)  //return true if dead  bool LLCurl::Multi::doPerform()  { -	if(mDeletionMutexp) -	{ -		mDeletionMutexp->lock() ; -	} +	LLMutexLock lock(mDeletionMutexp) ; +	  	bool dead = mDead ;  	if(mDead) @@ -675,6 +674,7 @@ bool LLCurl::Multi::doPerform()  				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)  			{ @@ -688,11 +688,6 @@ bool LLCurl::Multi::doPerform()  		setState(STATE_COMPLETED) ;  	} -	if(mDeletionMutexp) -	{ -		mDeletionMutexp->unlock() ; -	} -  	return dead ;  } @@ -715,10 +710,19 @@ S32 LLCurl::Multi::process()  		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 ; + +			{ +				LLMutexLock lock(mEasyMutexp) ; +				easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle); +				if (iter != mEasyActiveMap.end()) +				{ +					easy = iter->second; +				} +			} + +			if(easy)  			{ -				Easy* easy = iter->second;  				response = easy->report(msg->data.result);  				removeEasy(easy);  			} @@ -743,19 +747,21 @@ S32 LLCurl::Multi::process()  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;  	} @@ -764,6 +770,7 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()  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) @@ -776,22 +783,41 @@ bool LLCurl::Multi::addEasy(Easy* easy)  void LLCurl::Multi::easyFree(Easy* easy)  { +	if(mEasyMutexp) +	{ +		mEasyMutexp->lock() ; +	} +  	mEasyActiveList.erase(easy);  	mEasyActiveMap.erase(easy->getCurlHandle()); +  	if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) -	{ -		easy->resetState(); +	{		  		mEasyFreeList.insert(easy); +		 +		if(mEasyMutexp) +		{ +			mEasyMutexp->unlock() ; +		} + +		easy->resetState();  	}  	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);  } @@ -834,11 +860,17 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)  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) @@ -1290,6 +1322,10 @@ void LLCurl::initClass(bool multi_threaded)  #endif  	sCurlThread = new LLCurlThread(multi_threaded) ; +	if(multi_threaded) +	{ +		Easy::sHandleMutexp = new LLMutex(NULL) ; +	}  }  void LLCurl::cleanupClass() @@ -1319,6 +1355,9 @@ void LLCurl::cleanupClass()  	Easy::sFreeHandles.clear(); +	delete Easy::sHandleMutexp ; +	Easy::sHandleMutexp = NULL ; +  	llassert(Easy::sActiveHandles.empty());  } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index a275db3e53..705cdcbbcc 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -253,6 +253,7 @@ private:  	static std::set<CURL*> sFreeHandles;  	static std::set<CURL*> sActiveHandles; +	static LLMutex*        sHandleMutexp ;  };  class LLCurl::Multi @@ -298,6 +299,7 @@ public:  	S32 mQueued;  	S32 mErrorCount; +	static CURLM* initMulti() ;  private:  	void easyFree(LLCurl::Easy*); @@ -316,6 +318,9 @@ private:  	BOOL mDead ;  	LLMutex* mMutexp ;  	LLMutex* mDeletionMutexp ; +	LLMutex* mEasyMutexp ; + +	static LLMutex* sMultiInitMutexp ;  };  class LLCurlThread : public LLQueuedThread diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a076374903..045c9017be 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -250,6 +250,12 @@ LLIMWellChiclet::LLIMWellChiclet(const Params& p)  LLIMWellChiclet::~LLIMWellChiclet()  { +	LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance(); +	if (im_well_window) +	{ +		im_well_window->setSysWellChiclet(NULL); +	} +  	LLIMMgr::getInstance()->removeSessionObserver(this);  } diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index 85a7e75271..6f98be1cb8 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -408,9 +408,16 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)  	}  	// remove related chiclet -	LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id); +	if (LLChicletBar::instanceExists()) +	{ +		LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id); +	} -	LLIMWellWindow::getInstance()->removeObjectRow(notification_id); +	LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance(); +	if (im_well_window) +	{ +		im_well_window->removeObjectRow(notification_id); +	}  	mNotifications.erase(notification_id); diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 3aa6a3b7e5..0cb6c85012 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -159,6 +159,7 @@ void LLSysWellWindow::setVisible(BOOL visible)  	LLTransientDockableFloater::setVisible(visible);  	// update notification channel state	 +	initChannel(); // make sure the channel still exists  	if(mChannel)  	{  		mChannel->updateShowToastsState(); @@ -598,6 +599,13 @@ LLIMWellWindow* LLIMWellWindow::getInstance(const LLSD& key /*= LLSD()*/)  	return LLFloaterReg::getTypedInstance<LLIMWellWindow>("im_well_window", key);  } + +// static +LLIMWellWindow* LLIMWellWindow::findInstance(const LLSD& key /*= LLSD()*/) +{ +	return LLFloaterReg::findTypedInstance<LLIMWellWindow>("im_well_window", key); +} +  BOOL LLIMWellWindow::postBuild()  {  	BOOL rv = LLSysWellWindow::postBuild(); @@ -751,7 +759,10 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)  {  	if (mMessageList->removeItemByValue(notification_id))  	{ -		mSysWellChiclet->updateWidget(isWindowEmpty()); +		if (mSysWellChiclet) +		{ +			mSysWellChiclet->updateWidget(isWindowEmpty()); +		}  	}  	else  	{ diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 52e5370505..272e9cfcb1 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -153,6 +153,7 @@ public:  	~LLIMWellWindow();  	static LLIMWellWindow* getInstance(const LLSD& key = LLSD()); +	static LLIMWellWindow* findInstance(const LLSD& key = LLSD());  	static void initClass() { getInstance(); }  	/*virtual*/ BOOL postBuild(); | 
