summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2012-03-08 17:58:25 -0700
committerXiaohong Bao <bao@lindenlab.com>2012-03-08 17:58:25 -0700
commit88edb8da4e0c2610a85777c824bff67d645f716c (patch)
tree609cdfcf081d3d775a918da52c5e5f296c1c2fa0 /indra
parent5e74293b0cfe562e8e3184217f27b3e86afe5277 (diff)
fix for MAINT-701: crash at LLCurl::Multi::markDead()
reviewed by davep
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llcurl.cpp48
-rw-r--r--indra/llmessage/llcurl.h3
2 files changed, 34 insertions, 17 deletions
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 2ef43d9c00..bac3e6c426 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -548,6 +548,7 @@ LLCurl::Multi::Multi(F32 idle_time_out)
mErrorCount(0),
mState(STATE_READY),
mDead(FALSE),
+ mValid(TRUE),
mMutexp(NULL),
mDeletionMutexp(NULL),
mEasyMutexp(NULL)
@@ -584,6 +585,9 @@ LLCurl::Multi::Multi(F32 idle_time_out)
LLCurl::Multi::~Multi()
{
cleanup(true) ;
+
+ delete mDeletionMutexp ;
+ mDeletionMutexp = NULL ;
}
void LLCurl::Multi::cleanup(bool deleted)
@@ -592,7 +596,10 @@ void LLCurl::Multi::cleanup(bool deleted)
{
return ; //nothing to clean.
}
+ llassert_always(deleted || !mValid) ;
+ LLMutexLock lock(mDeletionMutexp);
+
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
@@ -615,14 +622,12 @@ void LLCurl::Multi::cleanup(bool deleted)
check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
mCurlMultiHandle = NULL ;
-
+
delete mMutexp ;
mMutexp = NULL ;
- delete mDeletionMutexp ;
- mDeletionMutexp = NULL ;
delete mEasyMutexp ;
mEasyMutexp = NULL ;
-
+
mQueued = 0 ;
mState = STATE_COMPLETED;
@@ -649,10 +654,20 @@ void LLCurl::Multi::unlock()
void LLCurl::Multi::markDead()
{
- LLMutexLock lock(mDeletionMutexp) ;
+ {
+ LLMutexLock lock(mDeletionMutexp) ;
+
+ if(mCurlMultiHandle != NULL)
+ {
+ mDead = TRUE ;
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+
+ return;
+ }
+ }
- mDead = TRUE ;
- LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+ //not valid, delete it.
+ delete this;
}
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
@@ -746,10 +761,14 @@ bool LLCurl::Multi::doPerform()
setState(STATE_COMPLETED) ;
mIdleTimer.reset() ;
}
- else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+ else if(!mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
{
dead = true ;
}
+ else if(mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut - 1.f) //idle for too long, mark it invalid.
+ {
+ mValid = FALSE ;
+ }
return dead ;
}
@@ -971,14 +990,7 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)
return ;
}
- if(multi->isValid())
- {
- multi->markDead() ;
- }
- else
- {
- deleteMulti(multi) ;
- }
+ multi->markDead() ;
}
//private
@@ -997,6 +1009,10 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
void LLCurlThread::cleanupMulti(LLCurl::Multi* multi)
{
multi->cleanup() ;
+ if(multi->isDead()) //check if marked dead during cleaning up.
+ {
+ deleteMulti(multi) ;
+ }
}
//------------------------------------------------------------
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 579ba0b1ab..d6a7714d4c 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -304,7 +304,7 @@ public:
ePerformState getState() ;
bool isCompleted() ;
- bool isValid() {return mCurlMultiHandle != NULL ;}
+ bool isValid() {return mCurlMultiHandle != NULL && mValid;}
bool isDead() {return mDead;}
bool waitToComplete() ;
@@ -333,6 +333,7 @@ private:
ePerformState mState;
BOOL mDead ;
+ BOOL mValid ;
LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ;
LLMutex* mEasyMutexp ;