Skip to content
Snippets Groups Projects
Commit 4ec112bf authored by Xiaohong Bao's avatar Xiaohong Bao
Browse files

fix for SH-2738 and SH-2777, might also help SH-2723: heap corruption

SH-2738: Texture fetching freezes due to LLcurl
SH-2777: viewer crashed on logout in LLCurl::Easy::releaseEasyHandle
parent 2dc7df91
No related branches found
No related tags found
No related merge requests found
...@@ -187,11 +187,14 @@ class LLMutexLock ...@@ -187,11 +187,14 @@ class LLMutexLock
LLMutexLock(LLMutex* mutex) LLMutexLock(LLMutex* mutex)
{ {
mMutex = mutex; mMutex = mutex;
mMutex->lock();
if(mMutex)
mMutex->lock();
} }
~LLMutexLock() ~LLMutexLock()
{ {
mMutex->unlock(); if(mMutex)
mMutex->unlock();
} }
private: private:
LLMutex* mMutex; LLMutex* mMutex;
......
...@@ -219,11 +219,15 @@ namespace boost ...@@ -219,11 +219,15 @@ namespace boost
std::set<CURL*> LLCurl::Easy::sFreeHandles; std::set<CURL*> LLCurl::Easy::sFreeHandles;
std::set<CURL*> LLCurl::Easy::sActiveHandles; std::set<CURL*> LLCurl::Easy::sActiveHandles;
LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
//static //static
CURL* LLCurl::Easy::allocEasyHandle() CURL* LLCurl::Easy::allocEasyHandle()
{ {
CURL* ret = NULL; CURL* ret = NULL;
LLMutexLock lock(sHandleMutexp) ;
if (sFreeHandles.empty()) if (sFreeHandles.empty())
{ {
ret = curl_easy_init(); ret = curl_easy_init();
...@@ -251,6 +255,7 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle) ...@@ -251,6 +255,7 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)
llerrs << "handle cannot be NULL!" << llendl; llerrs << "handle cannot be NULL!" << llendl;
} }
LLMutexLock lock(sHandleMutexp) ;
if (sActiveHandles.find(handle) != sActiveHandles.end()) if (sActiveHandles.find(handle) != sActiveHandles.end())
{ {
sActiveHandles.erase(handle); sActiveHandles.erase(handle);
...@@ -519,7 +524,8 @@ LLCurl::Multi::Multi() ...@@ -519,7 +524,8 @@ LLCurl::Multi::Multi()
mState(STATE_READY), mState(STATE_READY),
mDead(FALSE), mDead(FALSE),
mMutexp(NULL), mMutexp(NULL),
mDeletionMutexp(NULL) mDeletionMutexp(NULL),
mEasyMutexp(NULL)
{ {
mCurlMultiHandle = curl_multi_init(); mCurlMultiHandle = curl_multi_init();
if (!mCurlMultiHandle) if (!mCurlMultiHandle)
...@@ -534,6 +540,7 @@ LLCurl::Multi::Multi() ...@@ -534,6 +540,7 @@ LLCurl::Multi::Multi()
{ {
mMutexp = new LLMutex(NULL) ; mMutexp = new LLMutex(NULL) ;
mDeletionMutexp = new LLMutex(NULL) ; mDeletionMutexp = new LLMutex(NULL) ;
mEasyMutexp = new LLMutex(NULL) ;
} }
LLCurl::getCurlThread()->addMulti(this) ; LLCurl::getCurlThread()->addMulti(this) ;
...@@ -563,6 +570,8 @@ LLCurl::Multi::~Multi() ...@@ -563,6 +570,8 @@ LLCurl::Multi::~Multi()
mMutexp = NULL ; mMutexp = NULL ;
delete mDeletionMutexp ; delete mDeletionMutexp ;
mDeletionMutexp = NULL ; mDeletionMutexp = NULL ;
delete mEasyMutexp ;
mEasyMutexp = NULL ;
--gCurlMultiCount; --gCurlMultiCount;
} }
...@@ -585,17 +594,9 @@ void LLCurl::Multi::unlock() ...@@ -585,17 +594,9 @@ void LLCurl::Multi::unlock()
void LLCurl::Multi::markDead() void LLCurl::Multi::markDead()
{ {
if(mDeletionMutexp) LLMutexLock lock(mDeletionMutexp) ;
{
mDeletionMutexp->lock() ;
}
mDead = TRUE ; mDead = TRUE ;
if(mDeletionMutexp)
{
mDeletionMutexp->unlock() ;
}
} }
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
...@@ -655,10 +656,8 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) ...@@ -655,10 +656,8 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
//return true if dead //return true if dead
bool LLCurl::Multi::doPerform() bool LLCurl::Multi::doPerform()
{ {
if(mDeletionMutexp) LLMutexLock lock(mDeletionMutexp) ;
{
mDeletionMutexp->lock() ;
}
bool dead = mDead ; bool dead = mDead ;
if(mDead) if(mDead)
...@@ -675,6 +674,7 @@ bool LLCurl::Multi::doPerform() ...@@ -675,6 +674,7 @@ bool LLCurl::Multi::doPerform()
call_count < MULTI_PERFORM_CALL_REPEAT; call_count < MULTI_PERFORM_CALL_REPEAT;
call_count++) call_count++)
{ {
LLMutexLock lock(mMutexp) ;
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
if (CURLM_CALL_MULTI_PERFORM != code || q == 0) if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
{ {
...@@ -688,11 +688,6 @@ bool LLCurl::Multi::doPerform() ...@@ -688,11 +688,6 @@ bool LLCurl::Multi::doPerform()
setState(STATE_COMPLETED) ; setState(STATE_COMPLETED) ;
} }
if(mDeletionMutexp)
{
mDeletionMutexp->unlock() ;
}
return dead ; return dead ;
} }
...@@ -743,19 +738,21 @@ S32 LLCurl::Multi::process() ...@@ -743,19 +738,21 @@ S32 LLCurl::Multi::process()
LLCurl::Easy* LLCurl::Multi::allocEasy() LLCurl::Easy* LLCurl::Multi::allocEasy()
{ {
Easy* easy = 0; Easy* easy = 0;
if (mEasyFreeList.empty()) if (mEasyFreeList.empty())
{ {
easy = Easy::getEasy(); easy = Easy::getEasy();
} }
else else
{ {
LLMutexLock lock(mEasyMutexp) ;
easy = *(mEasyFreeList.begin()); easy = *(mEasyFreeList.begin());
mEasyFreeList.erase(easy); mEasyFreeList.erase(easy);
} }
if (easy) if (easy)
{ {
LLMutexLock lock(mEasyMutexp) ;
mEasyActiveList.insert(easy); mEasyActiveList.insert(easy);
mEasyActiveMap[easy->getCurlHandle()] = easy; mEasyActiveMap[easy->getCurlHandle()] = easy;
} }
...@@ -764,6 +761,7 @@ LLCurl::Easy* LLCurl::Multi::allocEasy() ...@@ -764,6 +761,7 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()
bool LLCurl::Multi::addEasy(Easy* easy) bool LLCurl::Multi::addEasy(Easy* easy)
{ {
LLMutexLock lock(mMutexp) ;
CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle()); CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle());
check_curl_multi_code(mcode); check_curl_multi_code(mcode);
//if (mcode != CURLM_OK) //if (mcode != CURLM_OK)
...@@ -776,22 +774,30 @@ bool LLCurl::Multi::addEasy(Easy* easy) ...@@ -776,22 +774,30 @@ bool LLCurl::Multi::addEasy(Easy* easy)
void LLCurl::Multi::easyFree(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy)
{ {
mEasyMutexp->lock() ;
mEasyActiveList.erase(easy); mEasyActiveList.erase(easy);
mEasyActiveMap.erase(easy->getCurlHandle()); mEasyActiveMap.erase(easy->getCurlHandle());
if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE)
{ {
easy->resetState();
mEasyFreeList.insert(easy); mEasyFreeList.insert(easy);
mEasyMutexp->unlock() ;
easy->resetState();
} }
else else
{ {
mEasyMutexp->unlock() ;
delete easy; delete easy;
} }
} }
void LLCurl::Multi::removeEasy(Easy* 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); easyFree(easy);
} }
...@@ -1290,6 +1296,10 @@ void LLCurl::initClass(bool multi_threaded) ...@@ -1290,6 +1296,10 @@ void LLCurl::initClass(bool multi_threaded)
#endif #endif
sCurlThread = new LLCurlThread(multi_threaded) ; sCurlThread = new LLCurlThread(multi_threaded) ;
if(multi_threaded)
{
Easy::sHandleMutexp = new LLMutex(NULL) ;
}
} }
void LLCurl::cleanupClass() void LLCurl::cleanupClass()
...@@ -1319,6 +1329,9 @@ void LLCurl::cleanupClass() ...@@ -1319,6 +1329,9 @@ void LLCurl::cleanupClass()
Easy::sFreeHandles.clear(); Easy::sFreeHandles.clear();
delete Easy::sHandleMutexp ;
Easy::sHandleMutexp = NULL ;
llassert(Easy::sActiveHandles.empty()); llassert(Easy::sActiveHandles.empty());
} }
......
...@@ -253,6 +253,7 @@ class LLCurl::Easy ...@@ -253,6 +253,7 @@ class LLCurl::Easy
static std::set<CURL*> sFreeHandles; static std::set<CURL*> sFreeHandles;
static std::set<CURL*> sActiveHandles; static std::set<CURL*> sActiveHandles;
static LLMutex* sHandleMutexp ;
}; };
class LLCurl::Multi class LLCurl::Multi
...@@ -316,6 +317,7 @@ class LLCurl::Multi ...@@ -316,6 +317,7 @@ class LLCurl::Multi
BOOL mDead ; BOOL mDead ;
LLMutex* mMutexp ; LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ; LLMutex* mDeletionMutexp ;
LLMutex* mEasyMutexp ;
}; };
class LLCurlThread : public LLQueuedThread class LLCurlThread : public LLQueuedThread
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment