diff options
Diffstat (limited to 'indra/llmessage')
-rw-r--r-- | indra/llmessage/llcurl.cpp | 56 | ||||
-rw-r--r-- | indra/llmessage/llcurl.h | 5 | ||||
-rw-r--r-- | indra/llmessage/tests/llsdmessage_test.cpp | 36 |
3 files changed, 46 insertions, 51 deletions
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index b93d429feb..5ea9b58300 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) @@ -583,22 +584,33 @@ LLCurl::Multi::Multi(F32 idle_time_out) LLCurl::Multi::~Multi() { - cleanup() ; + cleanup(true) ; + + delete mDeletionMutexp ; + mDeletionMutexp = NULL ; } -void LLCurl::Multi::cleanup() +void LLCurl::Multi::cleanup(bool deleted) { if(!mCurlMultiHandle) { 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) { Easy* easy = *iter; check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); + + if(deleted) + { + easy->mResponder = NULL ; //avoid triggering mResponder. + } delete easy; } mEasyActiveList.clear(); @@ -610,11 +622,9 @@ void LLCurl::Multi::cleanup() check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle)); mCurlMultiHandle = NULL ; - + delete mMutexp ; mMutexp = NULL ; - delete mDeletionMutexp ; - mDeletionMutexp = NULL ; delete mEasyMutexp ; mEasyMutexp = NULL ; @@ -644,10 +654,20 @@ void LLCurl::Multi::unlock() void LLCurl::Multi::markDead() { - LLMutexLock lock(mDeletionMutexp) ; + { + LLMutexLock lock(mDeletionMutexp) ; - mDead = TRUE ; - LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; + if(mCurlMultiHandle != NULL) + { + mDead = TRUE ; + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; + + return; + } + } + + //not valid, delete it. + delete this; } void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) @@ -741,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 ; } @@ -966,15 +990,8 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi) return ; } - if(multi->isValid()) - { multi->markDead() ; } - else - { - deleteMulti(multi) ; - } -} //private bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi) @@ -992,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) ; + } } //------------------------------------------------------------ @@ -1506,7 +1527,8 @@ void LLCurl::cleanupClass() delete sHandleMutexp ; sHandleMutexp = NULL ; - llassert(Easy::sActiveHandles.empty()); + // removed as per https://jira.secondlife.com/browse/SH-3115 + //llassert(Easy::sActiveHandles.empty()); } //static diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index fd664c0fa1..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() ; @@ -318,7 +318,7 @@ public: private: void easyFree(LLCurl::Easy*); - void cleanup() ; + void cleanup(bool deleted = false) ; CURLM* mCurlMultiHandle; @@ -333,6 +333,7 @@ private: ePerformState mState; BOOL mDead ; + BOOL mValid ; LLMutex* mMutexp ; LLMutex* mDeletionMutexp ; LLMutex* mEasyMutexp ; diff --git a/indra/llmessage/tests/llsdmessage_test.cpp b/indra/llmessage/tests/llsdmessage_test.cpp index 31a791e4b4..44b024a83f 100644 --- a/indra/llmessage/tests/llsdmessage_test.cpp +++ b/indra/llmessage/tests/llsdmessage_test.cpp @@ -42,6 +42,7 @@ // external library headers // other Linden headers #include "../test/lltut.h" +#include "../test/catch_and_store_what_in.h" #include "llsdserialize.h" #include "llevents.h" #include "stringize.h" @@ -72,43 +73,14 @@ namespace tut template<> template<> void llsdmessage_object::test<1>() { - bool threw = false; + std::string threw; // This should fail... try { LLSDMessage localListener; } - catch (const LLEventPump::DupPumpName&) - { - threw = true; - } - catch (const std::runtime_error& ex) - { - // This clause is because on Linux, on the viewer side, for this - // one test program (though not others!), the - // LLEventPump::DupPumpName exception isn't caught by the clause - // above. Warn the user... - std::cerr << "Failed to catch " << typeid(ex).name() << std::endl; - // But if the expected exception was thrown, allow the test to - // succeed anyway. Not sure how else to handle this odd case. - if (std::string(typeid(ex).name()) == typeid(LLEventPump::DupPumpName).name()) - { - threw = true; - } - else - { - // We don't even recognize this exception. Let it propagate - // out to TUT to fail the test. - throw; - } - } - catch (...) - { - std::cerr << "Utterly failed to catch expected exception!" << std::endl; - // This case is full of fail. We HAVE to address it. - throw; - } - ensure("second LLSDMessage should throw", threw); + CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName) + ensure("second LLSDMessage should throw", ! threw.empty()); } template<> template<> |