From b4766d2fde6b74c5a4a50cdde4373b5261a020e2 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 21 Nov 2011 14:42:21 -0700 Subject: fix for sh-2601: [crashhunters] crash in LLBufferArray::countAfter() sh-2602: [crashhunters] crash on exit in ~LLPumpIO() --- indra/llmessage/llcurl.cpp | 356 ++++++++++++++++++++++++++++----------------- 1 file changed, 220 insertions(+), 136 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 330028c926..7f61e1ac04 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -86,9 +86,7 @@ S32 gCurlMultiCount = 0; std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; - -bool LLCurl::sMultiThreaded = false; -static U32 sMainThreadID = 0; +LLCurlThread* LLCurl::sCurlThread = NULL ; void check_curl_code(CURLcode code) { @@ -221,14 +219,11 @@ namespace boost std::set LLCurl::Easy::sFreeHandles; std::set LLCurl::Easy::sActiveHandles; -LLMutex* LLCurl::Easy::sHandleMutex = NULL; -LLMutex* LLCurl::Easy::sMultiMutex = NULL; //static CURL* LLCurl::Easy::allocEasyHandle() { CURL* ret = NULL; - LLMutexLock lock(sHandleMutex); if (sFreeHandles.empty()) { ret = curl_easy_init(); @@ -256,8 +251,6 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle) llerrs << "handle cannot be NULL!" << llendl; } - LLMutexLock lock(sHandleMutex); - if (sActiveHandles.find(handle) != sActiveHandles.end()) { sActiveHandles.erase(handle); @@ -521,23 +514,13 @@ void LLCurl::Easy::prepRequest(const std::string& url, //////////////////////////////////////////////////////////////////////////// LLCurl::Multi::Multi() - : LLThread("Curl Multi"), - mQueued(0), + : mQueued(0), mErrorCount(0), - mPerformState(PERFORM_STATE_READY) + mState(STATE_READY), + mDead(FALSE), + mMutexp(NULL), + mDeletionMutexp(NULL) { - mQuitting = false; - - mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID; - if (mThreaded) - { - mSignal = new LLCondition(NULL); - } - else - { - mSignal = NULL; - } - mCurlMultiHandle = curl_multi_init(); if (!mCurlMultiHandle) { @@ -545,22 +528,20 @@ LLCurl::Multi::Multi() mCurlMultiHandle = curl_multi_init(); } - llassert_always(mCurlMultiHandle); - ++gCurlMultiCount; -} - -LLCurl::Multi::~Multi() -{ - llassert(isStopped()); + llassert_always(mCurlMultiHandle); - if (LLCurl::sMultiThreaded) + if(LLCurl::getCurlThread()->getThreaded()) { - LLCurl::Easy::sMultiMutex->lock(); + mMutexp = new LLMutex(NULL) ; + mDeletionMutexp = new LLMutex(NULL) ; } + LLCurl::getCurlThread()->addMulti(this) ; - delete mSignal; - mSignal = NULL; + ++gCurlMultiCount; +} +LLCurl::Multi::~Multi() +{ // Clean up active for(easy_active_list_t::iterator iter = mEasyActiveList.begin(); iter != mEasyActiveList.end(); ++iter) @@ -577,75 +558,149 @@ LLCurl::Multi::~Multi() mEasyFreeList.clear(); check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle)); + + delete mMutexp ; + mMutexp = NULL ; + delete mDeletionMutexp ; + mDeletionMutexp = NULL ; + --gCurlMultiCount; +} - if (LLCurl::sMultiThreaded) +void LLCurl::Multi::lock() +{ + if(mMutexp) { - LLCurl::Easy::sMultiMutex->unlock(); + mMutexp->lock() ; } } -CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) +void LLCurl::Multi::unlock() { - CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue); - return curlmsg; + if(mMutexp) + { + mMutexp->unlock() ; + } } -void LLCurl::Multi::perform() +void LLCurl::Multi::markDead() { - if (mThreaded) + if(mDeletionMutexp) { - if (mPerformState == PERFORM_STATE_READY) - { - mSignal->signal(); - } + mDeletionMutexp->lock() ; } - else + + mDead = TRUE ; + + if(mDeletionMutexp) + { + mDeletionMutexp->unlock() ; + } +} + +void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) +{ + lock() ; + mState = state ; + if(mState == STATE_READY) { - doPerform(); + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL) ; } + unlock() ; } -void LLCurl::Multi::run() +LLCurl::Multi::ePerformState LLCurl::Multi::getState() { - llassert(mThreaded); + ePerformState state ; + + lock() ; + state = mState ; + unlock() ; + + return state ; +} + +bool LLCurl::Multi::isCompleted() +{ + return STATE_COMPLETED == getState() ; +} - while (!mQuitting) +bool LLCurl::Multi::waitToComplete() +{ + if(!mMutexp) //not threaded { - mSignal->wait(); - mPerformState = PERFORM_STATE_PERFORMING; - if (!mQuitting) - { - LLMutexLock lock(LLCurl::Easy::sMultiMutex); - doPerform(); - } + doPerform() ; + return true ; + } + + bool completed ; + + lock() ; + completed = (STATE_COMPLETED == mState) ; + if(!completed) + { + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; } + unlock() ; + + return completed; } -void LLCurl::Multi::doPerform() +CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) { - S32 q = 0; - for (S32 call_count = 0; - call_count < MULTI_PERFORM_CALL_REPEAT; - call_count += 1) + CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue); + return curlmsg; +} + +//return true if dead +bool LLCurl::Multi::doPerform() +{ + if(mDeletionMutexp) + { + mDeletionMutexp->lock() ; + } + bool dead = mDead ; + + if(mDead) { - CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); - if (CURLM_CALL_MULTI_PERFORM != code || q == 0) + setState(STATE_COMPLETED); + mQueued = 0 ; + } + else if(getState() != STATE_COMPLETED) + { + setState(STATE_PERFORMING); + + S32 q = 0; + for (S32 call_count = 0; + call_count < MULTI_PERFORM_CALL_REPEAT; + call_count++) { - check_curl_multi_code(code); - break; + CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); + if (CURLM_CALL_MULTI_PERFORM != code || q == 0) + { + check_curl_multi_code(code); + + break; + } } - + + mQueued = q; + setState(STATE_COMPLETED) ; } - mQueued = q; - mPerformState = PERFORM_STATE_COMPLETED; + + if(mDeletionMutexp) + { + mDeletionMutexp->unlock() ; + } + + return dead ; } S32 LLCurl::Multi::process() { - perform(); + waitToComplete() ; - if (mPerformState != PERFORM_STATE_COMPLETED) + if (getState() != STATE_COMPLETED) { return 0; } @@ -681,7 +736,8 @@ S32 LLCurl::Multi::process() } } - mPerformState = PERFORM_STATE_READY; + setState(STATE_READY); + return processed; } @@ -739,6 +795,75 @@ void LLCurl::Multi::removeEasy(Easy* easy) easyFree(easy); } +//------------------------------------------------------------ +//LLCurlThread +LLCurlThread::CurlRequest::CurlRequest(handle_t handle, LLCurl::Multi* multi) : + LLQueuedThread::QueuedRequest(handle, LLQueuedThread::PRIORITY_NORMAL, FLAG_AUTO_COMPLETE), + mMulti(multi) +{ +} + +LLCurlThread::CurlRequest::~CurlRequest() +{ + if(mMulti) + { + delete mMulti ; + mMulti = NULL ; + } +} + +bool LLCurlThread::CurlRequest::processRequest() +{ + bool completed = true ; + if(mMulti) + { + completed = mMulti->doPerform() ; + setPriority(LLQueuedThread::PRIORITY_LOW) ; + } + + return completed ; +} + +void LLCurlThread::CurlRequest::finishRequest(bool completed) +{ + delete mMulti ; + mMulti = NULL ; +} + +LLCurlThread::LLCurlThread(bool threaded) : + LLQueuedThread("curlthread", threaded) +{ +} + +//virtual +LLCurlThread::~LLCurlThread() +{ +} + +S32 LLCurlThread::update(U32 max_time_ms) +{ + return LLQueuedThread::update(max_time_ms); +} + +void LLCurlThread::addMulti(LLCurl::Multi* multi) +{ + multi->mHandle = generateHandle() ; + + CurlRequest* req = new CurlRequest(multi->mHandle, multi) ; + + if (!addRequest(req)) + { + llwarns << "curl request added when the thread is quitted" << llendl; + } +} + +void LLCurlThread::deleteMulti(LLCurl::Multi* multi) +{ + multi->markDead() ; +} + +//------------------------------------------------------------ + //static std::string LLCurl::strerror(CURLcode errorcode) { @@ -753,39 +878,23 @@ LLCurlRequest::LLCurlRequest() : mActiveMulti(NULL), mActiveRequestCount(0) { - mThreadID = LLThread::currentID(); mProcessing = FALSE; } LLCurlRequest::~LLCurlRequest() { - llassert_always(mThreadID == LLThread::currentID()); - //stop all Multi handle background threads for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter) { - LLCurl::Multi* multi = *iter; - multi->mQuitting = true; - if (multi->mThreaded) - { - while (!multi->isStopped()) - { - multi->mSignal->signal(); - apr_sleep(1000); - } - } + LLCurl::getCurlThread()->deleteMulti(*iter) ; } - for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer()); + mMultiSet.clear() ; } void LLCurlRequest::addMulti() { - llassert_always(mThreadID == LLThread::currentID()); LLCurl::Multi* multi = new LLCurl::Multi(); - if (multi->mThreaded) - { - multi->start(); - } + mMultiSet.insert(multi); mActiveMulti = multi; mActiveRequestCount = 0; @@ -901,7 +1010,6 @@ bool LLCurlRequest::post(const std::string& url, // Note: call once per frame S32 LLCurlRequest::process() { - llassert_always(mThreadID == LLThread::currentID()); S32 res = 0; mProcessing = TRUE; @@ -915,17 +1023,7 @@ S32 LLCurlRequest::process() if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0) { mMultiSet.erase(curiter); - multi->mQuitting = true; - if (multi->mThreaded) - { - while (!multi->isStopped()) - { - multi->mSignal->signal(); - apr_sleep(1000); - } - } - - delete multi; + LLCurl::getCurlThread()->deleteMulti(multi); } } mProcessing = FALSE; @@ -934,7 +1032,6 @@ S32 LLCurlRequest::process() S32 LLCurlRequest::getQueued() { - llassert_always(mThreadID == LLThread::currentID()); S32 queued = 0; for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ) @@ -942,7 +1039,7 @@ S32 LLCurlRequest::getQueued() curlmulti_set_t::iterator curiter = iter++; LLCurl::Multi* multi = *curiter; queued += multi->mQueued; - if (multi->mPerformState != LLCurl::Multi::PERFORM_STATE_READY) + if (multi->getState() != LLCurl::Multi::STATE_READY) { ++queued; } @@ -959,10 +1056,7 @@ LLCurlEasyRequest::LLCurlEasyRequest() mResultReturned(false) { mMulti = new LLCurl::Multi(); - if (mMulti->mThreaded) - { - mMulti->start(); - } + mEasy = mMulti->allocEasy(); if (mEasy) { @@ -975,16 +1069,7 @@ LLCurlEasyRequest::LLCurlEasyRequest() LLCurlEasyRequest::~LLCurlEasyRequest() { - mMulti->mQuitting = true; - if (mMulti->mThreaded) - { - while (!mMulti->isStopped()) - { - mMulti->mSignal->signal(); - apr_sleep(1000); - } - } - delete mMulti; + LLCurl::getCurlThread()->deleteMulti(mMulti) ; } void LLCurlEasyRequest::setopt(CURLoption option, S32 value) @@ -1080,19 +1165,14 @@ void LLCurlEasyRequest::requestComplete() } } -void LLCurlEasyRequest::perform() -{ - mMulti->perform(); -} - // Usage: Call getRestult until it returns false (no more messages) bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info) { - if (mMulti->mPerformState != LLCurl::Multi::PERFORM_STATE_COMPLETED) + if (!mMulti->isCompleted()) { //we're busy, try again later return false; } - mMulti->mPerformState = LLCurl::Multi::PERFORM_STATE_READY; + mMulti->setState(LLCurl::Multi::STATE_READY) ; if (!mEasy) { @@ -1180,8 +1260,6 @@ unsigned long LLCurl::ssl_thread_id(void) void LLCurl::initClass(bool multi_threaded) { - sMainThreadID = LLThread::currentID(); - sMultiThreaded = multi_threaded; // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" // - http://curl.haxx.se/libcurl/c/curl_global_init.html @@ -1189,9 +1267,6 @@ void LLCurl::initClass(bool multi_threaded) check_curl_code(code); - Easy::sHandleMutex = new LLMutex(NULL); - Easy::sMultiMutex = new LLMutex(NULL); - #if SAFE_SSL S32 mutex_count = CRYPTO_num_locks(); for (S32 i=0; iupdate(1)) //finish all tasks + { + break ; + } + } + sCurlThread->shutdown() ; + delete sCurlThread ; + sCurlThread = NULL ; + #if SAFE_SSL CRYPTO_set_locking_callback(NULL); for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer()); #endif - delete Easy::sHandleMutex; - Easy::sHandleMutex = NULL; - delete Easy::sMultiMutex; - Easy::sMultiMutex = NULL; - for (std::set::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) { CURL* curl = *iter; -- cgit v1.3 From 3fc4c14464c1b8152108a5332b754d5b2671e54d Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 29 Nov 2011 16:18:50 -0700 Subject: fix a mac build error: a friend declaration issue. --- indra/llmessage/llcurl.cpp | 32 ++++++++++++++++++++++---------- indra/llmessage/llcurl.h | 10 ++++++++-- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7f61e1ac04..7ca25d07fc 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -797,9 +797,10 @@ void LLCurl::Multi::removeEasy(Easy* easy) //------------------------------------------------------------ //LLCurlThread -LLCurlThread::CurlRequest::CurlRequest(handle_t handle, LLCurl::Multi* multi) : +LLCurlThread::CurlRequest::CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread) : LLQueuedThread::QueuedRequest(handle, LLQueuedThread::PRIORITY_NORMAL, FLAG_AUTO_COMPLETE), - mMulti(multi) + mMulti(multi), + mCurlThread(curl_thread) { } @@ -807,7 +808,7 @@ LLCurlThread::CurlRequest::~CurlRequest() { if(mMulti) { - delete mMulti ; + mCurlThread->deleteMulti(mMulti) ; mMulti = NULL ; } } @@ -817,7 +818,7 @@ bool LLCurlThread::CurlRequest::processRequest() bool completed = true ; if(mMulti) { - completed = mMulti->doPerform() ; + completed = mCurlThread->doMultiPerform(mMulti) ; setPriority(LLQueuedThread::PRIORITY_LOW) ; } @@ -826,7 +827,7 @@ bool LLCurlThread::CurlRequest::processRequest() void LLCurlThread::CurlRequest::finishRequest(bool completed) { - delete mMulti ; + mCurlThread->deleteMulti(mMulti) ; mMulti = NULL ; } @@ -849,7 +850,7 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi) { multi->mHandle = generateHandle() ; - CurlRequest* req = new CurlRequest(multi->mHandle, multi) ; + CurlRequest* req = new CurlRequest(multi->mHandle, multi, this) ; if (!addRequest(req)) { @@ -857,11 +858,22 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi) } } -void LLCurlThread::deleteMulti(LLCurl::Multi* multi) +void LLCurlThread::killMulti(LLCurl::Multi* multi) { multi->markDead() ; } +//private +bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi) +{ + return multi->doPerform() ; +} + +//private +void LLCurlThread::deleteMulti(LLCurl::Multi* multi) +{ + delete multi ; +} //------------------------------------------------------------ //static @@ -886,7 +898,7 @@ LLCurlRequest::~LLCurlRequest() //stop all Multi handle background threads for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter) { - LLCurl::getCurlThread()->deleteMulti(*iter) ; + LLCurl::getCurlThread()->killMulti(*iter) ; } mMultiSet.clear() ; } @@ -1023,7 +1035,7 @@ S32 LLCurlRequest::process() if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0) { mMultiSet.erase(curiter); - LLCurl::getCurlThread()->deleteMulti(multi); + LLCurl::getCurlThread()->killMulti(multi); } } mProcessing = FALSE; @@ -1069,7 +1081,7 @@ LLCurlEasyRequest::LLCurlEasyRequest() LLCurlEasyRequest::~LLCurlEasyRequest() { - LLCurl::getCurlThread()->deleteMulti(mMulti) ; + LLCurl::getCurlThread()->killMulti(mMulti) ; } void LLCurlEasyRequest::setopt(CURLoption option, S32 value) diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 23a6ca67e3..a275db3e53 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -328,7 +328,7 @@ public: virtual ~CurlRequest(); // use deleteRequest() public: - CurlRequest(handle_t handle, LLCurl::Multi* multi); + CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread); /*virtual*/ bool processRequest(); /*virtual*/ void finishRequest(bool completed); @@ -336,8 +336,10 @@ public: private: // input LLCurl::Multi* mMulti; + LLCurlThread* mCurlThread; }; - + friend class CurlRequest; + public: LLCurlThread(bool threaded = true) ; virtual ~LLCurlThread() ; @@ -345,6 +347,10 @@ public: S32 update(U32 max_time_ms); void addMulti(LLCurl::Multi* multi) ; + void killMulti(LLCurl::Multi* multi) ; + +private: + bool doMultiPerform(LLCurl::Multi* multi) ; void deleteMulti(LLCurl::Multi* multi) ; } ; -- cgit v1.3 From 09feaac844d67a94ffe8c98a201e1e7f2f84be9a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 5 Dec 2011 13:23:05 -0700 Subject: fix for sh-2738: Texture fetching freezes due to LLcurl --- indra/llcommon/llthread.h | 11 ++++++++-- indra/llmessage/llcurl.cpp | 54 +++++++++++++++++++++------------------------- 2 files changed, 34 insertions(+), 31 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 40291a2569..b0a1c9e12b 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -187,11 +187,18 @@ 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..228f039132 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -585,37 +585,30 @@ 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() ; + LLMutexLock lock(mMutexp) ; + mState = state ; if(mState == STATE_READY) { LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL) ; } - unlock() ; } LLCurl::Multi::ePerformState LLCurl::Multi::getState() { ePerformState state ; - lock() ; - state = mState ; - unlock() ; + { + LLMutexLock lock(mMutexp) ; + state = mState ; + } return state ; } @@ -635,13 +628,15 @@ bool LLCurl::Multi::waitToComplete() bool completed ; - lock() ; - completed = (STATE_COMPLETED == mState) ; - if(!completed) { - LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; + LLMutexLock lock(mMutexp) ; + + completed = (STATE_COMPLETED == mState) ; + if(!completed) + { + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; + } } - unlock() ; return completed; } @@ -655,10 +650,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 +668,8 @@ 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 +683,6 @@ bool LLCurl::Multi::doPerform() setState(STATE_COMPLETED) ; } - if(mDeletionMutexp) - { - mDeletionMutexp->unlock() ; - } - return dead ; } @@ -764,6 +754,8 @@ 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,6 +768,8 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { + LLMutexLock lock(mMutexp) ; + mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) @@ -791,6 +785,8 @@ void LLCurl::Multi::easyFree(Easy* easy) void LLCurl::Multi::removeEasy(Easy* easy) { + LLMutexLock lock(mMutexp) ; + check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); easyFree(easy); } -- cgit v1.3 From 78233d1bf9930575ee7250257ac68603f41f568a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 5 Dec 2011 17:55:40 -0600 Subject: SH-2652 WIP -- Add timers to relevant areas, pause render pipeline while occlusion queries from previous frame are still pending and perform texture decode work. --- indra/llcommon/llqueuedthread.cpp | 4 ++-- indra/llcommon/llqueuedthread.h | 4 ++-- indra/llcommon/llworkerthread.cpp | 2 +- indra/llcommon/llworkerthread.h | 2 +- indra/llimage/llimageworker.cpp | 2 +- indra/llimage/llimageworker.h | 2 +- indra/llmessage/llcurl.cpp | 2 +- indra/llmessage/llcurl.h | 2 +- indra/newview/llappviewer.cpp | 8 +++++--- indra/newview/llspatialpartition.cpp | 26 ++++++++++++++++++++++++++ indra/newview/llspatialpartition.h | 2 ++ indra/newview/lltexturecache.cpp | 2 +- indra/newview/lltexturecache.h | 2 +- indra/newview/lltexturefetch.cpp | 2 +- indra/newview/lltexturefetch.h | 2 +- indra/newview/llviewertexture.cpp | 14 +++++++++++++- 16 files changed, 60 insertions(+), 18 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 5dee7a3541..1738c16dea 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -109,7 +109,7 @@ void LLQueuedThread::shutdown() // MAIN THREAD // virtual -S32 LLQueuedThread::update(U32 max_time_ms) +S32 LLQueuedThread::update(F32 max_time_ms) { if (!mStarted) { @@ -122,7 +122,7 @@ S32 LLQueuedThread::update(U32 max_time_ms) return updateQueue(max_time_ms); } -S32 LLQueuedThread::updateQueue(U32 max_time_ms) +S32 LLQueuedThread::updateQueue(F32 max_time_ms) { F64 max_time = (F64)max_time_ms * .001; LLTimer timer; diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 499d13a792..d3704b0fe2 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -173,8 +173,8 @@ protected: public: bool waitForResult(handle_t handle, bool auto_complete = true); - virtual S32 update(U32 max_time_ms); - S32 updateQueue(U32 max_time_ms); + virtual S32 update(F32 max_time_ms); + S32 updateQueue(F32 max_time_ms); void waitOnPending(); void printQueueStats(); diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4988bdf570..3d05a30ac2 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -81,7 +81,7 @@ void LLWorkerThread::clearDeleteList() } // virtual -S32 LLWorkerThread::update(U32 max_time_ms) +S32 LLWorkerThread::update(F32 max_time_ms) { S32 res = LLQueuedThread::update(max_time_ms); // Delete scheduled workers diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 78a4781d15..be46394d6e 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -86,7 +86,7 @@ public: LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false); ~LLWorkerThread(); - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 28dc3bd313..ad2eb0f69c 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -46,7 +46,7 @@ LLImageDecodeThread::~LLImageDecodeThread() // MAIN THREAD // virtual -S32 LLImageDecodeThread::update(U32 max_time_ms) +S32 LLImageDecodeThread::update(F32 max_time_ms) { LLMutexLock lock(mCreationMutex); for (creation_list_t::iterator iter = mCreationList.begin(); diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index c684222fa5..1bfb0ddfd3 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -78,7 +78,7 @@ public: handle_t decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder); - S32 update(U32 max_time_ms); + S32 update(F32 max_time_ms); // Used by unit tests to check the consistency of the thread instance S32 tut_size(); diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7ca25d07fc..ce0632668c 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -841,7 +841,7 @@ LLCurlThread::~LLCurlThread() { } -S32 LLCurlThread::update(U32 max_time_ms) +S32 LLCurlThread::update(F32 max_time_ms) { return LLQueuedThread::update(max_time_ms); } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index a275db3e53..2c95279438 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -344,7 +344,7 @@ public: LLCurlThread(bool threaded = true) ; virtual ~LLCurlThread() ; - S32 update(U32 max_time_ms); + S32 update(F32 max_time_ms); void addMulti(LLCurl::Multi* multi) ; void killMulti(LLCurl::Multi* multi) ; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e80475f096..9455bf9875 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1345,17 +1345,19 @@ bool LLAppViewer::mainLoop() { S32 work_pending = 0; S32 io_pending = 0; + F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + { LLFastTimer ftm(FTM_TEXTURE_CACHE); - work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread + work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread } { LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread + work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread } { LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread + work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread } { diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 3e16ccf3da..fb107a302a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -28,6 +28,10 @@ #include "llspatialpartition.h" +#include "llappviewer.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llimageworker.h" #include "llviewerwindow.h" #include "llviewerobjectlist.h" #include "llvovolume.h" @@ -1221,6 +1225,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { mOcclusionQuery[i] = 0; + mOcclusionIssued[i] = 0; mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; mVisible[i] = 0; } @@ -1543,6 +1548,8 @@ BOOL LLSpatialGroup::rebound() } static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait"); + void LLSpatialGroup::checkOcclusion() { if (LLPipeline::sUseOcclusion > 1) @@ -1560,6 +1567,22 @@ void LLSpatialGroup::checkOcclusion() if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + + if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) + { //query was issued last frame, wait until it's available + S32 max_loop = 1024; + LLFastTimer t(FTM_OCCLUSION_WAIT); + while (!available && max_loop-- > 0) + { + F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + //do some usefu work while we wait + LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread + LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread + LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread + + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + } } else { @@ -1679,6 +1702,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); + //store which frame this query was issued on + mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; + { LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index f0c8a372ee..899547ae4d 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -396,6 +396,8 @@ protected: U32 mState; U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; + U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; + S32 mLODHash; static S32 sLODSeed; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index e7a176f4f9..8632890bbb 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -760,7 +760,7 @@ LLTextureCache::~LLTextureCache() ////////////////////////////////////////////////////////////////////////////// //virtual -S32 LLTextureCache::update(U32 max_time_ms) +S32 LLTextureCache::update(F32 max_time_ms) { static LLFrameTimer timer ; static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 64e3a2658c..dd0cc9b4bd 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -101,7 +101,7 @@ public: LLTextureCache(bool threaded); ~LLTextureCache(); - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); void purgeCache(ELLPath location); void setReadOnly(BOOL read_only) ; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 56dfb61c4f..f18aa8b4e6 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2204,7 +2204,7 @@ void LLTextureFetch::commonUpdate() // MAIN THREAD //virtual -S32 LLTextureFetch::update(U32 max_time_ms) +S32 LLTextureFetch::update(F32 max_time_ms) { static LLCachedControl band_width(gSavedSettings,"ThrottleBandwidthKBPS"); diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index d101da1f4b..35df7d816f 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -55,7 +55,7 @@ public: class TFRequest; - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down. void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down. diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index b0f5361a79..1863992a22 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -417,9 +417,13 @@ const S32 min_non_tex_system_mem = (128<<20); // 128 MB F32 texmem_lower_bound_scale = 0.85f; F32 texmem_middle_bound_scale = 0.925f; +static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check"); + //static bool LLViewerTexture::isMemoryForTextureLow() { + LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK); + const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB @@ -459,6 +463,9 @@ bool LLViewerTexture::isMemoryForTextureLow() return low_mem ; } +static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_MEDIA("Media"); +static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_TEST("Test"); + //static void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity) { @@ -467,9 +474,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { + LLFastTimer t(FTM_TEXTURE_UPDATE_TEST); tester->update() ; } - LLViewerMediaTexture::updateClass() ; + + { + LLFastTimer t(FTM_TEXTURE_UPDATE_MEDIA); + LLViewerMediaTexture::updateClass() ; + } sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes -- cgit v1.3 From 50a57ba9fec0435a990338398d5c4f23c5cc91f0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 9 Dec 2011 12:23:04 -0600 Subject: Backed out changeset fafd857891b1 --- indra/llcommon/llthread.h | 11 ++-------- indra/llmessage/llcurl.cpp | 54 +++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 34 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b0a1c9e12b..40291a2569 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -187,18 +187,11 @@ public: LLMutexLock(LLMutex* mutex) { mMutex = mutex; - - if(mMutex) - { - mMutex->lock(); - } + mMutex->lock(); } ~LLMutexLock() { - if(mMutex) - { - mMutex->unlock(); - } + mMutex->unlock(); } private: LLMutex* mMutex; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 228f039132..7ca25d07fc 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -585,30 +585,37 @@ void LLCurl::Multi::unlock() void LLCurl::Multi::markDead() { - LLMutexLock lock(mDeletionMutexp) ; - + if(mDeletionMutexp) + { + mDeletionMutexp->lock() ; + } + mDead = TRUE ; + + if(mDeletionMutexp) + { + mDeletionMutexp->unlock() ; + } } void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) { - LLMutexLock lock(mMutexp) ; - + lock() ; mState = state ; if(mState == STATE_READY) { LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL) ; } + unlock() ; } LLCurl::Multi::ePerformState LLCurl::Multi::getState() { ePerformState state ; - { - LLMutexLock lock(mMutexp) ; - state = mState ; - } + lock() ; + state = mState ; + unlock() ; return state ; } @@ -628,15 +635,13 @@ bool LLCurl::Multi::waitToComplete() bool completed ; + lock() ; + completed = (STATE_COMPLETED == mState) ; + if(!completed) { - LLMutexLock lock(mMutexp) ; - - completed = (STATE_COMPLETED == mState) ; - if(!completed) - { - LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; - } + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; } + unlock() ; return completed; } @@ -650,8 +655,10 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) //return true if dead bool LLCurl::Multi::doPerform() { - LLMutexLock lock(mDeletionMutexp) ; - + if(mDeletionMutexp) + { + mDeletionMutexp->lock() ; + } bool dead = mDead ; if(mDead) @@ -668,8 +675,6 @@ 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) { @@ -683,6 +688,11 @@ bool LLCurl::Multi::doPerform() setState(STATE_COMPLETED) ; } + if(mDeletionMutexp) + { + mDeletionMutexp->unlock() ; + } + return dead ; } @@ -754,8 +764,6 @@ 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) @@ -768,8 +776,6 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { - LLMutexLock lock(mMutexp) ; - mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) @@ -785,8 +791,6 @@ void LLCurl::Multi::easyFree(Easy* easy) void LLCurl::Multi::removeEasy(Easy* easy) { - LLMutexLock lock(mMutexp) ; - check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); easyFree(easy); } -- cgit v1.3 From 4ec112bfce19d4bf09ef79b3b3195dda24148730 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 15 Dec 2011 21:39:48 -0700 Subject: 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 --- indra/llcommon/llthread.h | 7 ++++-- indra/llmessage/llcurl.cpp | 63 ++++++++++++++++++++++++++++------------------ indra/llmessage/llcurl.h | 2 ++ 3 files changed, 45 insertions(+), 27 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') 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 ce0632668c..874f4673ca 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -219,11 +219,15 @@ namespace boost std::set LLCurl::Easy::sFreeHandles; std::set 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); @@ -519,7 +524,8 @@ LLCurl::Multi::Multi() mState(STATE_READY), mDead(FALSE), mMutexp(NULL), - mDeletionMutexp(NULL) + mDeletionMutexp(NULL), + mEasyMutexp(NULL) { mCurlMultiHandle = curl_multi_init(); if (!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,6 +570,8 @@ LLCurl::Multi::~Multi() mMutexp = NULL ; delete mDeletionMutexp ; mDeletionMutexp = NULL ; + delete mEasyMutexp ; + mEasyMutexp = NULL ; --gCurlMultiCount; } @@ -585,17 +594,9 @@ 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) @@ -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 ; } @@ -743,19 +738,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 +761,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 +774,30 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { + mEasyMutexp->lock() ; mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); + if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) - { - easy->resetState(); + { mEasyFreeList.insert(easy); + mEasyMutexp->unlock() ; + + easy->resetState(); } else { + 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); } @@ -1290,6 +1296,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 +1329,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 2c95279438..eb814bc608 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -253,6 +253,7 @@ private: static std::set sFreeHandles; static std::set sActiveHandles; + static LLMutex* sHandleMutexp ; }; class LLCurl::Multi @@ -316,6 +317,7 @@ private: BOOL mDead ; LLMutex* mMutexp ; LLMutex* mDeletionMutexp ; + LLMutex* mEasyMutexp ; }; class LLCurlThread : public LLQueuedThread -- cgit v1.3 From efec138037d7271effd89536d824bec270985909 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 15 Dec 2011 21:39:48 -0700 Subject: 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 --- indra/llcommon/llthread.h | 7 ++++-- indra/llmessage/llcurl.cpp | 63 ++++++++++++++++++++++++++++------------------ indra/llmessage/llcurl.h | 2 ++ 3 files changed, 45 insertions(+), 27 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') 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..d86bf7a0a1 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -219,11 +219,15 @@ namespace boost std::set LLCurl::Easy::sFreeHandles; std::set 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); @@ -519,7 +524,8 @@ LLCurl::Multi::Multi() mState(STATE_READY), mDead(FALSE), mMutexp(NULL), - mDeletionMutexp(NULL) + mDeletionMutexp(NULL), + mEasyMutexp(NULL) { mCurlMultiHandle = curl_multi_init(); if (!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,6 +570,8 @@ LLCurl::Multi::~Multi() mMutexp = NULL ; delete mDeletionMutexp ; mDeletionMutexp = NULL ; + delete mEasyMutexp ; + mEasyMutexp = NULL ; --gCurlMultiCount; } @@ -585,17 +594,9 @@ 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) @@ -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 ; } @@ -743,19 +738,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 +761,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 +774,30 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { + mEasyMutexp->lock() ; mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); + if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) - { - easy->resetState(); + { mEasyFreeList.insert(easy); + mEasyMutexp->unlock() ; + + easy->resetState(); } else { + 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); } @@ -1290,6 +1296,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 +1329,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..5d54b5fe12 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -253,6 +253,7 @@ private: static std::set sFreeHandles; static std::set sActiveHandles; + static LLMutex* sHandleMutexp ; }; class LLCurl::Multi @@ -316,6 +317,7 @@ private: BOOL mDead ; LLMutex* mMutexp ; LLMutex* mDeletionMutexp ; + LLMutex* mEasyMutexp ; }; class LLCurlThread : public LLQueuedThread -- cgit v1.3 From 58f9982fbc94ed2f039f0cd32579fa572f87e8ba Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Dec 2011 15:35:38 -0600 Subject: SH-2738 Add comment documenting need to not make main thread wait on curl_multi_perform --- indra/llmessage/llcurl.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 874f4673ca..20f0c6c602 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -675,6 +675,10 @@ bool LLCurl::Multi::doPerform() call_count++) { LLMutexLock lock(mMutexp) ; + + //WARNING: curl_multi_perform will block for many hundreds of milliseconds + // NEVER call this from the main thread, and NEVER allow the main thread to + // wait on a mutex held by this thread while curl_multi_perform is executing CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); if (CURLM_CALL_MULTI_PERFORM != code || q == 0) { -- cgit v1.3 From 43e3603cd763f5f501c8c5dc008d8a00d0744c53 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Dec 2011 16:55:21 -0600 Subject: SH-2738 Don't lock unless we really need to --- indra/llmessage/llcurl.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index d86bf7a0a1..988c12d6fb 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -612,13 +612,7 @@ void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) LLCurl::Multi::ePerformState LLCurl::Multi::getState() { - ePerformState state ; - - lock() ; - state = mState ; - unlock() ; - - return state ; + return mState; } bool LLCurl::Multi::isCompleted() @@ -636,14 +630,12 @@ bool LLCurl::Multi::waitToComplete() bool completed ; - lock() ; completed = (STATE_COMPLETED == mState) ; if(!completed) { LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; } - unlock() ; - + return completed; } -- cgit v1.3 From 5affaf264da937cdf825bf174c3905a6063b5336 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Dec 2011 16:55:21 -0600 Subject: SH-2738 Don't lock unless we really need to --- indra/llmessage/llcurl.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 20f0c6c602..05f3869a11 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -612,13 +612,7 @@ void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) LLCurl::Multi::ePerformState LLCurl::Multi::getState() { - ePerformState state ; - - lock() ; - state = mState ; - unlock() ; - - return state ; + return mState; } bool LLCurl::Multi::isCompleted() @@ -636,14 +630,12 @@ bool LLCurl::Multi::waitToComplete() bool completed ; - lock() ; completed = (STATE_COMPLETED == mState) ; if(!completed) { LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; } - unlock() ; - + return completed; } -- cgit v1.3 From cfc6ac76e1c700c0810629b005f45747c4144867 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 20 Dec 2011 11:04:10 -0700 Subject: more tuning of llcurl code targeting crashes like SH-2777. --- indra/llmessage/llcurl.cpp | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 988c12d6fb..2b351d351e 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -603,11 +603,12 @@ 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() @@ -628,9 +629,7 @@ bool LLCurl::Multi::waitToComplete() return true ; } - bool completed ; - - completed = (STATE_COMPLETED == mState) ; + bool completed = (STATE_COMPLETED == mState) ; if(!completed) { LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; @@ -641,6 +640,8 @@ bool LLCurl::Multi::waitToComplete() CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) { + LLMutexLock lock(mMutexp) ; + CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue); return curlmsg; } @@ -702,10 +703,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); } @@ -766,20 +776,31 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { - mEasyMutexp->lock() ; + if(mEasyMutexp) + { + mEasyMutexp->lock() ; + } + mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) { mEasyFreeList.insert(easy); - mEasyMutexp->unlock() ; + + if(mEasyMutexp) + { + mEasyMutexp->unlock() ; + } easy->resetState(); } else { - mEasyMutexp->unlock() ; + if(mEasyMutexp) + { + mEasyMutexp->unlock() ; + } delete easy; } } -- cgit v1.3 From 1620ad6d00a77b2089e0ae5f6de30f9a954c6167 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 20 Dec 2011 11:04:10 -0700 Subject: more tuning of llcurl code targeting crashes like SH-2777. --- indra/llmessage/llcurl.cpp | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 05f3869a11..5027e8fa84 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -603,11 +603,12 @@ 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() @@ -628,9 +629,7 @@ bool LLCurl::Multi::waitToComplete() return true ; } - bool completed ; - - completed = (STATE_COMPLETED == mState) ; + bool completed = (STATE_COMPLETED == mState) ; if(!completed) { LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; @@ -641,6 +640,8 @@ bool LLCurl::Multi::waitToComplete() CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) { + LLMutexLock lock(mMutexp) ; + CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue); return curlmsg; } @@ -706,10 +707,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); } @@ -770,20 +780,31 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { - mEasyMutexp->lock() ; + if(mEasyMutexp) + { + mEasyMutexp->lock() ; + } + mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) { mEasyFreeList.insert(easy); - mEasyMutexp->unlock() ; + + if(mEasyMutexp) + { + mEasyMutexp->unlock() ; + } easy->resetState(); } else { - mEasyMutexp->unlock() ; + if(mEasyMutexp) + { + mEasyMutexp->unlock() ; + } delete easy; } } -- cgit v1.3 From ec06aa129f839cc98aaa8006d6467241281da9fa Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 20 Dec 2011 15:02:21 -0700 Subject: add mutex to protect curl_multi-init() --- indra/llmessage/llcurl.cpp | 19 ++++++++++++++++--- indra/llmessage/llcurl.h | 3 +++ 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 2b351d351e..f569630766 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -517,7 +517,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, } //////////////////////////////////////////////////////////////////////////// - +LLMutex* LLCurl::Multi::sMultiInitMutexp = NULL ; LLCurl::Multi::Multi() : mQueued(0), mErrorCount(0), @@ -527,11 +527,11 @@ LLCurl::Multi::Multi() 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); @@ -576,6 +576,13 @@ LLCurl::Multi::~Multi() --gCurlMultiCount; } +CURLM* LLCurl::Multi::initMulti() +{ + LLMutexLock lock(sMultiInitMutexp) ; + + return curl_multi_init() ; +} + void LLCurl::Multi::lock() { if(mMutexp) @@ -853,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) diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 5d54b5fe12..705cdcbbcc 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -299,6 +299,7 @@ public: S32 mQueued; S32 mErrorCount; + static CURLM* initMulti() ; private: void easyFree(LLCurl::Easy*); @@ -318,6 +319,8 @@ private: LLMutex* mMutexp ; LLMutex* mDeletionMutexp ; LLMutex* mEasyMutexp ; + + static LLMutex* sMultiInitMutexp ; }; class LLCurlThread : public LLQueuedThread -- cgit v1.3 From f082de03ff24ae8cc6a2de103bc643c392135742 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 12 Jan 2012 16:36:56 -0700 Subject: fix for SH-2845, SH-2846, SH-2847, SH-2851: curl crashes and out-of-memory crashes. --- indra/llmessage/llcurl.cpp | 293 +++++++++++++++++---- indra/llmessage/llcurl.h | 22 +- indra/llmessage/llhttpassetstorage.cpp | 10 +- indra/llmessage/llhttpclient.cpp | 12 +- indra/llmessage/lliopipe.cpp | 6 + indra/llmessage/lliopipe.h | 2 + indra/llmessage/llpumpio.cpp | 50 +++- indra/llmessage/llpumpio.h | 12 +- indra/llmessage/llsdrpcclient.h | 3 + indra/llmessage/llurlrequest.cpp | 18 ++ indra/llmessage/llurlrequest.h | 2 + indra/newview/llmeshrepository.cpp | 131 +++++---- indra/newview/llmeshrepository.h | 4 +- indra/newview/llxmlrpctransaction.cpp | 19 ++ .../updater/llupdatedownloader.cpp | 23 +- 15 files changed, 475 insertions(+), 132 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index e17380fdf5..eab2874596 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -72,10 +72,12 @@ static const U32 EASY_HANDLE_POOL_SIZE = 5; static const S32 MULTI_PERFORM_CALL_REPEAT = 5; -static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds +static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation static const S32 MAX_ACTIVE_REQUEST_COUNT = 100; -static +static const F32 DEFAULT_MULTI_IDLE_TIME = 120.0f ; //seconds +static const S32 MAX_NUM_OF_HANDLES = 256 ; //max number of handles, (multi handles and easy handles combined). + // DEBUG // S32 gCurlEasyCount = 0; S32 gCurlMultiCount = 0; @@ -87,6 +89,8 @@ std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; LLCurlThread* LLCurl::sCurlThread = NULL ; +LLMutex* LLCurl::sHandleMutexp = NULL ; +S32 LLCurl::sTotalHandles = 0 ; void check_curl_code(CURLcode code) { @@ -230,7 +234,7 @@ CURL* LLCurl::Easy::allocEasyHandle() if (sFreeHandles.empty()) { - ret = curl_easy_init(); + ret = LLCurl::newEasyHandle(); } else { @@ -250,16 +254,27 @@ CURL* LLCurl::Easy::allocEasyHandle() //static void LLCurl::Easy::releaseEasyHandle(CURL* handle) { + static const S32 MAX_NUM_FREE_HANDLES = 32 ; + if (!handle) { - llerrs << "handle cannot be NULL!" << llendl; + return ; //handle allocation failed. + //llerrs << "handle cannot be NULL!" << llendl; } LLMutexLock lock(sHandleMutexp) ; if (sActiveHandles.find(handle) != sActiveHandles.end()) { sActiveHandles.erase(handle); - sFreeHandles.insert(handle); + + if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES) + { + sFreeHandles.insert(handle); + } + else + { + LLCurl::deleteEasyHandle(handle) ; + } } else { @@ -517,8 +532,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, } //////////////////////////////////////////////////////////////////////////// -LLMutex* LLCurl::Multi::sMultiInitMutexp = NULL ; -LLCurl::Multi::Multi() +LLCurl::Multi::Multi(F32 idle_time_out) : mQueued(0), mErrorCount(0), mState(STATE_READY), @@ -527,28 +541,47 @@ LLCurl::Multi::Multi() mDeletionMutexp(NULL), mEasyMutexp(NULL) { - mCurlMultiHandle = initMulti(); + mCurlMultiHandle = LLCurl::newMultiHandle(); if (!mCurlMultiHandle) { llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; - mCurlMultiHandle = initMulti(); + mCurlMultiHandle = LLCurl::newMultiHandle(); } - llassert_always(mCurlMultiHandle); - - if(LLCurl::getCurlThread()->getThreaded()) + //llassert_always(mCurlMultiHandle); + + if(mCurlMultiHandle) { - mMutexp = new LLMutex(NULL) ; - mDeletionMutexp = new LLMutex(NULL) ; - mEasyMutexp = new LLMutex(NULL) ; - } - LLCurl::getCurlThread()->addMulti(this) ; + if(LLCurl::getCurlThread()->getThreaded()) + { + mMutexp = new LLMutex(NULL) ; + mDeletionMutexp = new LLMutex(NULL) ; + mEasyMutexp = new LLMutex(NULL) ; + } + LLCurl::getCurlThread()->addMulti(this) ; + + mIdleTimeOut = idle_time_out ; + if(mIdleTimeOut < DEFAULT_MULTI_IDLE_TIME) + { + mIdleTimeOut = DEFAULT_MULTI_IDLE_TIME ; + } - ++gCurlMultiCount; + ++gCurlMultiCount; + } } LLCurl::Multi::~Multi() { + cleanup() ; +} + +void LLCurl::Multi::cleanup() +{ + if(!mCurlMultiHandle) + { + return ; //nothing to clean. + } + // Clean up active for(easy_active_list_t::iterator iter = mEasyActiveList.begin(); iter != mEasyActiveList.end(); ++iter) @@ -564,7 +597,8 @@ LLCurl::Multi::~Multi() for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer()); mEasyFreeList.clear(); - check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle)); + check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle)); + mCurlMultiHandle = NULL ; delete mMutexp ; mMutexp = NULL ; @@ -572,15 +606,13 @@ LLCurl::Multi::~Multi() mDeletionMutexp = NULL ; delete mEasyMutexp ; mEasyMutexp = NULL ; - + + mQueued = 0 ; + mState = STATE_COMPLETED; + --gCurlMultiCount; -} - -CURLM* LLCurl::Multi::initMulti() -{ - LLMutexLock lock(sMultiInitMutexp) ; - return curl_multi_init() ; + return ; } void LLCurl::Multi::lock() @@ -604,6 +636,7 @@ void LLCurl::Multi::markDead() LLMutexLock lock(mDeletionMutexp) ; mDead = TRUE ; + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; } void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) @@ -630,6 +663,11 @@ bool LLCurl::Multi::isCompleted() bool LLCurl::Multi::waitToComplete() { + if(!isValid()) + { + return true ; + } + if(!mMutexp) //not threaded { doPerform() ; @@ -639,7 +677,7 @@ bool LLCurl::Multi::waitToComplete() bool completed = (STATE_COMPLETED == mState) ; if(!completed) { - LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; + LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_HIGH) ; } return completed; @@ -689,7 +727,12 @@ bool LLCurl::Multi::doPerform() } mQueued = q; - setState(STATE_COMPLETED) ; + setState(STATE_COMPLETED) ; + mIdleTimer.reset() ; + } + else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it. + { + dead = true ; } return dead ; @@ -697,6 +740,11 @@ bool LLCurl::Multi::doPerform() S32 LLCurl::Multi::process() { + if(!isValid()) + { + return 0 ; + } + waitToComplete() ; if (getState() != STATE_COMPLETED) @@ -849,7 +897,11 @@ bool LLCurlThread::CurlRequest::processRequest() if(mMulti) { completed = mCurlThread->doMultiPerform(mMulti) ; - setPriority(LLQueuedThread::PRIORITY_LOW) ; + + if(!completed) + { + setPriority(LLQueuedThread::PRIORITY_LOW) ; + } } return completed ; @@ -857,24 +909,26 @@ bool LLCurlThread::CurlRequest::processRequest() void LLCurlThread::CurlRequest::finishRequest(bool completed) { - mCurlThread->deleteMulti(mMulti) ; + if(mMulti->isDead()) + { + mCurlThread->deleteMulti(mMulti) ; + } + else + { + mMulti->cleanup() ; //being idle too long, remove the request. + } + mMulti = NULL ; } 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(F32 max_time_ms) @@ -896,7 +950,19 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi) void LLCurlThread::killMulti(LLCurl::Multi* multi) { - multi->markDead() ; + if(!multi) + { + return ; + } + + if(multi->isValid()) + { + multi->markDead() ; + } + else + { + deleteMulti(multi) ; + } } //private @@ -942,7 +1008,14 @@ LLCurlRequest::~LLCurlRequest() void LLCurlRequest::addMulti() { LLCurl::Multi* multi = new LLCurl::Multi(); - + if(!multi->isValid()) + { + LLCurl::getCurlThread()->killMulti(multi) ; + mActiveMulti = NULL ; + mActiveRequestCount = 0 ; + return; + } + mMultiSet.insert(multi); mActiveMulti = multi; mActiveRequestCount = 0; @@ -1066,6 +1139,19 @@ S32 LLCurlRequest::process() { curlmulti_set_t::iterator curiter = iter++; LLCurl::Multi* multi = *curiter; + + if(!multi->isValid()) + { + if(multi == mActiveMulti) + { + mActiveMulti = NULL ; + mActiveRequestCount = 0 ; + } + mMultiSet.erase(curiter) ; + LLCurl::getCurlThread()->killMulti(multi) ; + continue ; + } + S32 tres = multi->process(); res += tres; if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0) @@ -1086,6 +1172,19 @@ S32 LLCurlRequest::getQueued() { curlmulti_set_t::iterator curiter = iter++; LLCurl::Multi* multi = *curiter; + + if(!multi->isValid()) + { + if(multi == mActiveMulti) + { + mActiveMulti = NULL ; + mActiveRequestCount = 0 ; + } + LLCurl::getCurlThread()->killMulti(multi); + mMultiSet.erase(curiter) ; + continue ; + } + queued += multi->mQueued; if (multi->getState() != LLCurl::Multi::STATE_READY) { @@ -1105,13 +1204,22 @@ LLCurlEasyRequest::LLCurlEasyRequest() { mMulti = new LLCurl::Multi(); - mEasy = mMulti->allocEasy(); - if (mEasy) + if(mMulti->isValid()) { - mEasy->setErrorBuffer(); - mEasy->setCA(); - // Set proxy settings if configured to do so. - LLProxy::getInstance()->applyProxySettings(mEasy); + mEasy = mMulti->allocEasy(); + if (mEasy) + { + mEasy->setErrorBuffer(); + mEasy->setCA(); + // Set proxy settings if configured to do so. + LLProxy::getInstance()->applyProxySettings(mEasy); + } + } + else + { + LLCurl::getCurlThread()->killMulti(mMulti) ; + mEasy = NULL ; + mMulti = NULL ; } } @@ -1122,7 +1230,7 @@ LLCurlEasyRequest::~LLCurlEasyRequest() void LLCurlEasyRequest::setopt(CURLoption option, S32 value) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setopt(option, value); } @@ -1130,7 +1238,7 @@ void LLCurlEasyRequest::setopt(CURLoption option, S32 value) void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setoptString(option, value); } @@ -1138,7 +1246,7 @@ void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value void LLCurlEasyRequest::setPost(char* postdata, S32 size) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setopt(CURLOPT_POST, 1); mEasy->setopt(CURLOPT_POSTFIELDS, postdata); @@ -1148,7 +1256,7 @@ void LLCurlEasyRequest::setPost(char* postdata, S32 size) void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* userdata) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setopt(CURLOPT_HEADERFUNCTION, (void*)callback); mEasy->setopt(CURLOPT_HEADERDATA, userdata); // aka CURLOPT_WRITEHEADER @@ -1157,7 +1265,7 @@ void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* u void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* userdata) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setopt(CURLOPT_WRITEFUNCTION, (void*)callback); mEasy->setopt(CURLOPT_WRITEDATA, userdata); @@ -1166,7 +1274,7 @@ void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* use void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userdata) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setopt(CURLOPT_READFUNCTION, (void*)callback); mEasy->setopt(CURLOPT_READDATA, userdata); @@ -1175,7 +1283,7 @@ void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userd void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata) { - if (mEasy) + if (isValid() && mEasy) { mEasy->setopt(CURLOPT_SSL_CTX_FUNCTION, (void*)callback); mEasy->setopt(CURLOPT_SSL_CTX_DATA, userdata); @@ -1184,7 +1292,7 @@ void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* void LLCurlEasyRequest::slist_append(const char* str) { - if (mEasy) + if (isValid() && mEasy) { mEasy->slist_append(str); } @@ -1195,7 +1303,7 @@ void LLCurlEasyRequest::sendRequest(const std::string& url) llassert_always(!mRequestSent); mRequestSent = true; lldebugs << url << llendl; - if (mEasy) + if (isValid() && mEasy) { mEasy->setHeaders(); mEasy->setoptString(CURLOPT_URL, url); @@ -1207,7 +1315,7 @@ void LLCurlEasyRequest::requestComplete() { llassert_always(mRequestSent); mRequestSent = false; - if (mEasy) + if (isValid() && mEasy) { mMulti->removeEasy(mEasy); } @@ -1216,6 +1324,10 @@ void LLCurlEasyRequest::requestComplete() // Usage: Call getRestult until it returns false (no more messages) bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info) { + if(!isValid()) + { + return false ; + } if (!mMulti->isCompleted()) { //we're busy, try again later return false; @@ -1280,7 +1392,7 @@ CURLMsg* LLCurlEasyRequest::info_read(S32* q, LLCurl::TransferInfo* info) std::string LLCurlEasyRequest::getErrorString() { - return mEasy ? std::string(mEasy->getErrorBuffer()) : std::string(); + return isValid() && mEasy ? std::string(mEasy->getErrorBuffer()) : std::string(); } //////////////////////////////////////////////////////////////////////////// @@ -1328,6 +1440,7 @@ void LLCurl::initClass(bool multi_threaded) sCurlThread = new LLCurlThread(multi_threaded) ; if(multi_threaded) { + sHandleMutexp = new LLMutex(NULL) ; Easy::sHandleMutexp = new LLMutex(NULL) ; } } @@ -1354,7 +1467,7 @@ void LLCurl::cleanupClass() for (std::set::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) { CURL* curl = *iter; - curl_easy_cleanup(curl); + LLCurl::deleteEasyHandle(curl); } Easy::sFreeHandles.clear(); @@ -1362,9 +1475,77 @@ void LLCurl::cleanupClass() delete Easy::sHandleMutexp ; Easy::sHandleMutexp = NULL ; + delete sHandleMutexp ; + sHandleMutexp = NULL ; + llassert(Easy::sActiveHandles.empty()); } +//static +CURLM* LLCurl::newMultiHandle() +{ + LLMutexLock lock(sHandleMutexp) ; + + if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES) + { + llwarns << "no more handles available." << llendl ; + return NULL ; //failed + } + sTotalHandles++; + + CURLM* ret = curl_multi_init() ; + if(!ret) + { + llwarns << "curl_multi_init failed." << llendl ; + } + + return ret ; +} + +//static +CURLMcode LLCurl::deleteMultiHandle(CURLM* handle) +{ + if(handle) + { + LLMutexLock lock(sHandleMutexp) ; + sTotalHandles-- ; + return curl_multi_cleanup(handle) ; + } + return CURLM_OK ; +} + +//static +CURL* LLCurl::newEasyHandle() +{ + LLMutexLock lock(sHandleMutexp) ; + + if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES) + { + llwarns << "no more handles available." << llendl ; + return NULL ; //failed + } + sTotalHandles++; + + CURL* ret = curl_easy_init() ; + if(!ret) + { + llwarns << "curl_easy_init failed." << llendl ; + } + + return ret ; +} + +//static +void LLCurl::deleteEasyHandle(CURL* handle) +{ + if(handle) + { + LLMutexLock lock(sHandleMutexp) ; + curl_easy_cleanup(handle) ; + sTotalHandles-- ; + } +} + const unsigned int LLCurl::MAX_REDIRECTS = 5; // Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace. diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 9c2c215c7a..32da911cbf 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -43,6 +43,7 @@ #include "llsd.h" #include "llthread.h" #include "llqueuedthread.h" +#include "llframetimer.h" class LLMutex; class LLCurlThread; @@ -182,11 +183,20 @@ public: static unsigned long ssl_thread_id(void); static LLCurlThread* getCurlThread() { return sCurlThread ;} + + static CURLM* newMultiHandle() ; + static CURLMcode deleteMultiHandle(CURLM* handle) ; + static CURL* newEasyHandle() ; + static void deleteEasyHandle(CURL* handle) ; + private: static std::string sCAPath; static std::string sCAFile; static const unsigned int MAX_REDIRECTS; static LLCurlThread* sCurlThread; + + static LLMutex* sHandleMutexp ; + static S32 sTotalHandles ; }; class LLCurl::Easy @@ -277,7 +287,7 @@ public: STATE_COMPLETED=2 } ePerformState; - Multi(); + Multi(F32 idle_time_out = 0.f); LLCurl::Easy* allocEasy(); bool addEasy(LLCurl::Easy* easy); @@ -288,7 +298,10 @@ public: void setState(ePerformState state) ; ePerformState getState() ; + bool isCompleted() ; + bool isValid() {return mCurlMultiHandle != NULL ;} + bool isDead() {return mDead;} bool waitToComplete() ; @@ -299,9 +312,9 @@ public: S32 mQueued; S32 mErrorCount; - static CURLM* initMulti() ; private: void easyFree(LLCurl::Easy*); + void cleanup() ; CURLM* mCurlMultiHandle; @@ -319,8 +332,8 @@ private: LLMutex* mMutexp ; LLMutex* mDeletionMutexp ; LLMutex* mEasyMutexp ; - - static LLMutex* sMultiInitMutexp ; + LLFrameTimer mIdleTimer ; + F32 mIdleTimeOut; }; class LLCurlThread : public LLQueuedThread @@ -414,6 +427,7 @@ public: std::string getErrorString(); bool isCompleted() {return mMulti->isCompleted() ;} bool wait() { return mMulti->waitToComplete(); } + bool isValid() {return mMulti && mMulti->isValid(); } LLCurl::Easy* getEasy() const { return mEasy; } diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 2bca517e97..612d765969 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -232,7 +232,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const void LLHTTPAssetRequest::setupCurlHandle() { // *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC - mCurlHandle = curl_easy_init(); + mCurlHandle = LLCurl::newEasyHandle(); + llassert_always(mCurlHandle != NULL) ; // Apply proxy settings if configured to do so LLProxy::getInstance()->applyProxySettings(mCurlHandle); @@ -278,7 +279,7 @@ void LLHTTPAssetRequest::setupCurlHandle() void LLHTTPAssetRequest::cleanupCurlHandle() { - curl_easy_cleanup(mCurlHandle); + LLCurl::deleteEasyHandle(mCurlHandle); if (mAssetStoragep) { // Terminating a request. Thus upload or download is no longer pending. @@ -429,12 +430,13 @@ void LLHTTPAssetStorage::_init(const std::string& web_host, const std::string& l // curl_global_init moved to LLCurl::initClass() - mCurlMultiHandle = curl_multi_init(); + mCurlMultiHandle = LLCurl::newMultiHandle() ; + llassert_always(mCurlMultiHandle != NULL) ; } LLHTTPAssetStorage::~LLHTTPAssetStorage() { - curl_multi_cleanup(mCurlMultiHandle); + LLCurl::deleteMultiHandle(mCurlMultiHandle); mCurlMultiHandle = NULL; // curl_global_cleanup moved to LLCurl::initClass() diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index dd4e3a6300..231cb7ca8f 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -228,6 +228,12 @@ static void request( LLPumpIO::chain_t chain; LLURLRequest* req = new LLURLRequest(method, url); + if(!req->isValid())//failed + { + delete req ; + return ; + } + req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req); @@ -423,7 +429,9 @@ static LLSD blocking_request( { lldebugs << "blockingRequest of " << url << llendl; char curl_error_buffer[CURL_ERROR_SIZE] = "\0"; - CURL* curlp = curl_easy_init(); + CURL* curlp = LLCurl::newEasyHandle(); + llassert_always(curlp != NULL) ; + LLHTTPBuffer http_buffer; std::string body_str; @@ -517,7 +525,7 @@ static LLSD blocking_request( } // * Cleanup - curl_easy_cleanup(curlp); + LLCurl::deleteEasyHandle(curlp); return response; } diff --git a/indra/llmessage/lliopipe.cpp b/indra/llmessage/lliopipe.cpp index 6e4eec74a6..8f827f7a30 100644 --- a/indra/llmessage/lliopipe.cpp +++ b/indra/llmessage/lliopipe.cpp @@ -75,6 +75,12 @@ LLIOPipe::~LLIOPipe() //lldebugs << "destroying LLIOPipe" << llendl; } +//virtual +bool LLIOPipe::isValid() +{ + return true ; +} + // static std::string LLIOPipe::lookupStatusString(EStatus status) { diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h index 8e656b6da1..cbd17b5a3d 100644 --- a/indra/llmessage/lliopipe.h +++ b/indra/llmessage/lliopipe.h @@ -231,6 +231,8 @@ public: */ virtual ~LLIOPipe(); + virtual bool isValid() ; + protected: /** * @brief Base Constructor. diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index a8d2a0a224..0ff300efd0 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -195,7 +195,7 @@ bool LLPumpIO::prime(apr_pool_t* pool) return ((pool == NULL) ? false : true); } -bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) +bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); if(chain.empty()) return false; @@ -204,6 +204,7 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) LLScopedLock lock(mChainsMutex); #endif LLChainInfo info; + info.mHasCurlRequest = has_curl_request; info.setTimeoutSeconds(timeout); info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray); LLLinkInfo link; @@ -440,6 +441,15 @@ void LLPumpIO::pump() static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO"); +LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain) +{ + std::for_each( + (*run_chain).mDescriptors.begin(), + (*run_chain).mDescriptors.end(), + ll_delete_apr_pollset_fd_client_data()); + return mRunningChains.erase(run_chain); +} + //timeout is in microseconds void LLPumpIO::pump(const S32& poll_timeout) { @@ -585,10 +595,16 @@ void LLPumpIO::pump(const S32& poll_timeout) // << (*run_chain).mChainLinks[0].mPipe // << " because we reached the end." << llendl; #endif - run_chain = mRunningChains.erase(run_chain); + run_chain = removeRunningChain(run_chain); continue; } } + else if(isChainExpired(*run_chain)) + { + run_chain = removeRunningChain(run_chain); + continue; + } + PUMP_DEBUG; if((*run_chain).mLock) { @@ -696,11 +712,7 @@ void LLPumpIO::pump(const S32& poll_timeout) PUMP_DEBUG; // This chain is done. Clean up any allocated memory and // erase the chain info. - std::for_each( - (*run_chain).mDescriptors.begin(), - (*run_chain).mDescriptors.end(), - ll_delete_apr_pollset_fd_client_data()); - run_chain = mRunningChains.erase(run_chain); + run_chain = removeRunningChain(run_chain); // *NOTE: may not always need to rebuild the pollset. mRebuildPollset = true; @@ -1095,6 +1107,24 @@ void LLPumpIO::processChain(LLChainInfo& chain) PUMP_DEBUG; } +bool LLPumpIO::isChainExpired(LLChainInfo& chain) +{ + if(!chain.mHasCurlRequest) + { + return false ; + } + + for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter) + { + if(!(*iter).mPipe->isValid()) + { + return true ; + } + } + + return false ; +} + bool LLPumpIO::handleChainError( LLChainInfo& chain, LLIOPipe::EStatus error) @@ -1136,6 +1166,9 @@ bool LLPumpIO::handleChainError( #endif keep_going = false; break; + case LLIOPipe::STATUS_EXPIRED: + keep_going = false; + break ; default: if(LLIOPipe::isSuccess(error)) { @@ -1157,7 +1190,8 @@ bool LLPumpIO::handleChainError( LLPumpIO::LLChainInfo::LLChainInfo() : mInit(false), mLock(0), - mEOS(false) + mEOS(false), + mHasCurlRequest(false) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index 9303c9d7fc..e405124403 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -113,7 +113,7 @@ public: * expire. Pass in 0.0f to never expire. * @return Returns true if anything was added to the pump. */ - bool addChain(const chain_t& chain, F32 timeout); + bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false); /** * @brief Struct to associate a pipe with it's buffer io indexes. @@ -356,12 +356,13 @@ protected: // basic member data bool mInit; + bool mEOS; + bool mHasCurlRequest; S32 mLock; LLFrameTimer mTimer; links_t::iterator mHead; links_t mChainLinks; - LLIOPipe::buffer_ptr_t mData; - bool mEOS; + LLIOPipe::buffer_ptr_t mData; LLSD mContext; // tracking inside the pump @@ -402,7 +403,7 @@ protected: protected: void initialize(apr_pool_t* pool); void cleanup(); - + current_chain_t removeRunningChain(current_chain_t& chain) ; /** * @brief Given the internal state of the chains, rebuild the pollset * @see setConditional() @@ -429,6 +430,9 @@ protected: */ bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error); + //if the chain is expired, remove it + bool isChainExpired(LLChainInfo& chain) ; + public: /** * @brief Return number of running chains. diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h index 9fb49a5c33..235077179e 100644 --- a/indra/llmessage/llsdrpcclient.h +++ b/indra/llmessage/llsdrpcclient.h @@ -239,6 +239,8 @@ public: LLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {} virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const { + llerrs << "Can not call this." << llendl ; + lldebugs << "LLSDRPCClientFactory::build" << llendl; LLIOPipe::ptr_t service(new Client); chain.push_back(service); @@ -282,6 +284,7 @@ public: LLXMLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {} virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const { + llerrs << "who calls this?" << llendl ; lldebugs << "LLXMLSDRPCClientFactory::build" << llendl; LLIOPipe::ptr_t service(new Client); chain.push_back(service); diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 261e57e79e..f02c636838 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -83,6 +83,12 @@ LLURLRequestDetail::LLURLRequestDetail() : { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mCurlRequest = new LLCurlEasyRequest(); + + if(!mCurlRequest->isValid()) //failed. + { + delete mCurlRequest ; + mCurlRequest = NULL ; + } } LLURLRequestDetail::~LLURLRequestDetail() @@ -250,12 +256,24 @@ void LLURLRequest::allowCookies() mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, ""); } +//virtual +bool LLURLRequest::isValid() +{ + return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid(); +} + // virtual LLIOPipe::EStatus LLURLRequest::handleError( LLIOPipe::EStatus status, LLPumpIO* pump) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); + + if(!isValid()) + { + return STATUS_EXPIRED ; + } + if(mCompletionCallback && pump) { LLURLRequestComplete* complete = NULL; diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index ec5c2c1941..44d358d906 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -188,6 +188,8 @@ public: */ void allowCookies(); + /*virtual*/ bool isValid() ; + public: /** * @brief Give this pipe a chance to handle a generated error diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a97e256c89..c64479f589 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -498,9 +498,11 @@ void LLMeshRepoThread::run() LODRequest req = mLODReqQ.front(); mLODReqQ.pop(); mMutex->unlock(); - if (fetchMeshLOD(req.mMeshParams, req.mLOD)) + if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit { - count++; + mMutex->lock(); + mLODReqQ.push(req) ; + mMutex->unlock(); } } } @@ -512,9 +514,11 @@ void LLMeshRepoThread::run() HeaderRequest req = mHeaderReqQ.front(); mHeaderReqQ.pop(); mMutex->unlock(); - if (fetchMeshHeader(req.mMeshParams)) + if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit { - count++; + mMutex->lock(); + mHeaderReqQ.push(req) ; + mMutex->unlock(); } } } @@ -658,6 +662,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) return false; } + bool ret = true ; U32 header_size = mMeshHeaderSize[mesh_id]; if (header_size > 0) @@ -673,7 +678,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) //check VFS for mesh skin info LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); if (file.getSize() >= offset+size) - { + { LLMeshRepository::sCacheBytesRead += size; file.seek(offset); U8* buffer = new U8[size]; @@ -689,7 +694,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) if (!zero) { //attempt to parse if (skinInfoReceived(mesh_id, buffer, size)) - { + { delete[] buffer; return true; } @@ -704,11 +709,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) - { - ++sActiveLODRequests; - LLMeshRepository::sHTTPRequestCount++; - mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, + { + ret = mCurlRequest->getByteRange(http_url, headers, offset, size, new LLMeshSkinInfoResponder(mesh_id, offset, size)); + if(ret) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + } } } } @@ -718,7 +726,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) } //early out was not hit, effectively fetched - return true; + return ret; } bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) @@ -732,7 +740,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) } U32 header_size = mMeshHeaderSize[mesh_id]; - + bool ret = true ; + if (header_size > 0) { S32 version = mMeshHeader[mesh_id]["version"].asInteger(); @@ -748,6 +757,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesRead += size; + file.seek(offset); U8* buffer = new U8[size]; file.read(buffer, size); @@ -777,11 +787,14 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) - { - ++sActiveLODRequests; - LLMeshRepository::sHTTPRequestCount++; - mCurlRequest->getByteRange(http_url, headers, offset, size, + { + ret = mCurlRequest->getByteRange(http_url, headers, offset, size, new LLMeshDecompositionResponder(mesh_id, offset, size)); + if(ret) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + } } } } @@ -791,7 +804,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) } //early out was not hit, effectively fetched - return true; + return ret; } bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) @@ -805,6 +818,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } U32 header_size = mMeshHeaderSize[mesh_id]; + bool ret = true ; if (header_size > 0) { @@ -850,11 +864,15 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) - { - ++sActiveLODRequests; - LLMeshRepository::sHTTPRequestCount++; - mCurlRequest->getByteRange(http_url, headers, offset, size, + { + ret = mCurlRequest->getByteRange(http_url, headers, offset, size, new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); + + if(ret) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + } } } else @@ -868,13 +886,12 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } //early out was not hit, effectively fetched - return true; + return ret; } -bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) +//return false if failed to get header +bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count) { - bool retval = false; - { //look for mesh in asset in vfs LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH); @@ -889,36 +906,40 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) file.read(buffer, bytes); if (headerReceived(mesh_params, buffer, bytes)) { //did not do an HTTP request, return false - return false; + return true; } } } - //either cache entry doesn't exist or is corrupt, request header from simulator - + //either cache entry doesn't exist or is corrupt, request header from simulator + bool retval = true ; std::vector headers; headers.push_back("Accept: application/octet-stream"); std::string http_url = constructUrl(mesh_params.getSculptID()); if (!http_url.empty()) { - ++sActiveHeaderRequests; - retval = true; //grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits //within the first 4KB - //NOTE -- this will break of headers ever exceed 4KB - LLMeshRepository::sHTTPRequestCount++; - mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params)); + //NOTE -- this will break of headers ever exceed 4KB + retval = mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params)); + if(retval) + { + ++sActiveHeaderRequests; + LLMeshRepository::sHTTPRequestCount++; + } + count++; } return retval; } -bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +//return false if failed to get mesh lod. +bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count) { //protected by mMutex mHeaderMutex->lock(); - bool retval = false; + bool retval = true; LLUUID mesh_id = mesh_params.getSculptID(); @@ -955,7 +976,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) if (lodReceived(mesh_params, lod, buffer, size)) { delete[] buffer; - return false; + return true; } } @@ -968,12 +989,16 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) - { - ++sActiveLODRequests; - retval = true; - LLMeshRepository::sHTTPRequestCount++; - mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, + { + retval = mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, new LLMeshLODResponder(mesh_params, lod, offset, size)); + + if(retval) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + } + count++; } else { @@ -1540,8 +1565,17 @@ void LLMeshUploadThread::doWholeModelUpload() LLSD body = full_model_data["asset_resources"]; dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num)); LLCurlRequest::headers_t headers; - mCurlRequest->post(mWholeModelUploadURL, headers, body, - new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle), mMeshUploadTimeOut); + + { + LLCurl::ResponderPtr responder = new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle) ; + + while(!mCurlRequest->post(mWholeModelUploadURL, headers, body, responder, mMeshUploadTimeOut)) + { + //sleep for 10ms to prevent eating a whole core + apr_sleep(10000); + } + } + do { mCurlRequest->process(); @@ -1571,8 +1605,15 @@ void LLMeshUploadThread::requestWholeModelFee() mPendingUploads++; LLCurlRequest::headers_t headers; - mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, - new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle), mMeshUploadTimeOut); + + { + LLCurl::ResponderPtr responder = new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle) ; + while(!mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, responder, mMeshUploadTimeOut)) + { + //sleep for 10ms to prevent eating a whole core + apr_sleep(10000); + } + } do { diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 31b84ea0d9..2efe810438 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -323,8 +323,8 @@ public: virtual void run(); void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); - bool fetchMeshHeader(const LLVolumeParams& mesh_params); - bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count); + bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count); bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 920a9a3752..0da70d398b 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -305,6 +305,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip) { mCurlRequest = new LLCurlEasyRequest(); } + if(!mCurlRequest->isValid()) + { + llwarns << "mCurlRequest is invalid." << llendl ; + + delete mCurlRequest ; + mCurlRequest = NULL ; + return ; + } + mErrorCert = NULL; // mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging @@ -357,10 +366,20 @@ LLXMLRPCTransaction::Impl::~Impl() } delete mCurlRequest; + mCurlRequest = NULL ; } bool LLXMLRPCTransaction::Impl::process() { + if(!mCurlRequest || !mCurlRequest->isValid()) + { + llwarns << "transaction failed." << llendl ; + + delete mCurlRequest ; + mCurlRequest = NULL ; + return true ; //failed, quit. + } + switch(mStatus) { case LLXMLRPCTransaction::StatusComplete: diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index e88d1bf811..19ac418e9e 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -39,7 +39,7 @@ #include "llsdserialize.h" #include "llthread.h" #include "llupdaterservice.h" - +#include "llcurl.h" class LLUpdateDownloader::Implementation: public LLThread @@ -198,13 +198,19 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & LLUpdateDownloader::Implementation::~Implementation() { - if(isDownloading()) { + if(isDownloading()) + { cancel(); shutdown(); - } else { + } + else + { ; // No op. } - if(mCurl) curl_easy_cleanup(mCurl); + if(mCurl) + { + LLCurl::deleteEasyHandle(mCurl); + } } @@ -406,9 +412,12 @@ void LLUpdateDownloader::Implementation::run(void) void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader) { - if(mCurl == 0) { - mCurl = curl_easy_init(); - } else { + if(mCurl == 0) + { + mCurl = LLCurl::newEasyHandle(); + } + else + { curl_easy_reset(mCurl); } -- cgit v1.3 From 11bd5cb86025376a198e45330116de4757b5c89e Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 12 Jan 2012 20:32:32 -0700 Subject: trivial: fix a mac build error. --- indra/llmessage/llcurl.cpp | 9 ++++++++- indra/llmessage/llcurl.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index eab2874596..277c274f52 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -915,7 +915,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed) } else { - mMulti->cleanup() ; //being idle too long, remove the request. + mCurlThread->cleanupMulti(mMulti) ; //being idle too long, remove the request. } mMulti = NULL ; @@ -976,6 +976,13 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi) { delete multi ; } + +//private +void LLCurlThread::cleanupMulti(LLCurl::Multi* multi) +{ + multi->cleanup() ; +} + //------------------------------------------------------------ //static diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 32da911cbf..2b23ac9763 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -370,6 +370,7 @@ public: private: bool doMultiPerform(LLCurl::Multi* multi) ; void deleteMulti(LLCurl::Multi* multi) ; + void cleanupMulti(LLCurl::Multi* multi) ; } ; namespace boost -- cgit v1.3 From 25c21c3761d871fa7927e2a5656ed18100084454 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 17 Jan 2012 22:56:28 -0700 Subject: add more exception handlings for llcurl fix. --- indra/llmessage/llcurl.cpp | 7 ++++++- indra/llmessage/llurlrequest.cpp | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 277c274f52..5edf0dc8c0 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -1036,7 +1036,12 @@ LLCurl::Easy* LLCurlRequest::allocEasy() { addMulti(); } - llassert_always(mActiveMulti); + if(!mActiveMulti) + { + return NULL ; + } + + //llassert_always(mActiveMulti); ++mActiveRequestCount; LLCurl::Easy* easy = mActiveMulti->allocEasy(); return easy; diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index f02c636838..a16f5c7bf0 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -459,6 +459,12 @@ void LLURLRequest::initialize() LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mState = STATE_INITIALIZED; mDetail = new LLURLRequestDetail; + + if(!isValid()) + { + return ; + } + mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this); mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this); -- cgit v1.3 From 9e6a5d721193f181c39e58fe00073bece74b081a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 20 Jan 2012 11:55:15 -0700 Subject: fix for SH-2823 and SH-2824: LLCurl crash inside LLBufferArray::countAfter() and LLBufferArray::copyIntoBuffers --- indra/llcommon/llthread.cpp | 15 ++++--- indra/llcommon/llthread.h | 1 + indra/llmessage/llbuffer.cpp | 90 +++++++++++++++++++++++++++++++++++++- indra/llmessage/llbuffer.h | 25 +++++++++++ indra/llmessage/llbufferstream.cpp | 8 ++++ indra/llmessage/llcurl.cpp | 3 ++ indra/llmessage/lliohttpserver.cpp | 4 +- indra/llmessage/lliosocket.cpp | 3 ++ indra/llmessage/llpumpio.cpp | 1 + 9 files changed, 142 insertions(+), 8 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 4063cc730b..a6ad6b125c 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -337,11 +337,7 @@ LLMutex::~LLMutex() void LLMutex::lock() { -#if LL_DARWIN - if (mLockingThread == LLThread::currentID()) -#else - if (mLockingThread == sThreadID) -#endif + if(isSelfLocked()) { //redundant lock mCount++; return; @@ -398,6 +394,15 @@ bool LLMutex::isLocked() } } +bool LLMutex::isSelfLocked() +{ +#if LL_DARWIN + return mLockingThread == LLThread::currentID(); +#else + return mLockingThread == sThreadID; +#endif +} + U32 LLMutex::lockingThread() const { return mLockingThread; diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index f0e0de6173..b52e70ab2e 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -151,6 +151,7 @@ public: void lock(); // blocks void unlock(); bool isLocked(); // non-blocking, but does do a lock/unlock so not free + bool isSelfLocked(); //return true if locked in a same thread U32 lockingThread() const; //get ID of locking thread protected: diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp index 0316797f00..250cace6e9 100644 --- a/indra/llmessage/llbuffer.cpp +++ b/indra/llmessage/llbuffer.cpp @@ -32,6 +32,9 @@ #include "llmath.h" #include "llmemtype.h" #include "llstl.h" +#include "llthread.h" + +#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked()); /** * LLSegment @@ -224,7 +227,8 @@ void LLHeapBuffer::allocate(S32 size) * LLBufferArray */ LLBufferArray::LLBufferArray() : - mNextBaseChannel(0) + mNextBaseChannel(0), + mMutexp(NULL) { LLMemType m1(LLMemType::MTYPE_IO_BUFFER); } @@ -233,6 +237,8 @@ LLBufferArray::~LLBufferArray() { LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer()); + + delete mMutexp; } // static @@ -243,14 +249,57 @@ LLChannelDescriptors LLBufferArray::makeChannelConsumer( return rv; } +void LLBufferArray::lock() +{ + if(mMutexp) + { + mMutexp->lock() ; + } +} + +void LLBufferArray::unlock() +{ + if(mMutexp) + { + mMutexp->unlock() ; + } +} + +LLMutex* LLBufferArray::getMutex() +{ + return mMutexp ; +} + +void LLBufferArray::setThreaded(bool threaded) +{ + if(threaded) + { + if(!mMutexp) + { + mMutexp = new LLMutex(NULL); + } + } + else + { + if(mMutexp) + { + delete mMutexp ; + mMutexp = NULL ; + } + } +} + LLChannelDescriptors LLBufferArray::nextChannel() { LLChannelDescriptors rv(mNextBaseChannel++); return rv; } +//mMutexp should be locked before calling this. S32 LLBufferArray::capacity() const { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED + S32 total = 0; const_buffer_iterator_t iter = mBuffers.begin(); const_buffer_iterator_t end = mBuffers.end(); @@ -263,6 +312,8 @@ S32 LLBufferArray::capacity() const bool LLBufferArray::append(S32 channel, const U8* src, S32 len) { + LLMutexLock lock(mMutexp) ; + LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::vector segments; if(copyIntoBuffers(channel, src, len, segments)) @@ -273,8 +324,11 @@ bool LLBufferArray::append(S32 channel, const U8* src, S32 len) return false; } +//mMutexp should be locked before calling this. bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED + LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::vector segments; if(copyIntoBuffers(channel, src, len, segments)) @@ -293,6 +347,8 @@ bool LLBufferArray::insertAfter( { LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::vector segments; + + LLMutexLock lock(mMutexp) ; if(mSegments.end() != segment) { ++segment; @@ -305,8 +361,11 @@ bool LLBufferArray::insertAfter( return false; } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED + LLMemType m1(LLMemType::MTYPE_IO_BUFFER); segment_iterator_t end = mSegments.end(); segment_iterator_t it = getSegment(address); @@ -335,20 +394,26 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address) return rv; } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::beginSegment() { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED return mSegments.begin(); } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::endSegment() { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED return mSegments.end(); } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter( U8* address, LLSegment& segment) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED LLMemType m1(LLMemType::MTYPE_IO_BUFFER); segment_iterator_t rv = mSegments.begin(); segment_iterator_t end = mSegments.end(); @@ -395,8 +460,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter( return rv; } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED segment_iterator_t end = mSegments.end(); if(!address) { @@ -414,9 +481,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address) return end; } +//mMutexp should be locked before calling this. LLBufferArray::const_segment_iterator_t LLBufferArray::getSegment( U8* address) const { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED const_segment_iterator_t end = mSegments.end(); if(!address) { @@ -466,6 +535,8 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const S32 count = 0; S32 offset = 0; const_segment_iterator_t it; + + LLMutexLock lock(mMutexp) ; const_segment_iterator_t end = mSegments.end(); if(start) { @@ -517,6 +588,8 @@ U8* LLBufferArray::readAfter( len = 0; S32 bytes_to_copy = 0; const_segment_iterator_t it; + + LLMutexLock lock(mMutexp) ; const_segment_iterator_t end = mSegments.end(); if(start) { @@ -568,6 +641,7 @@ U8* LLBufferArray::seek( U8* start, S32 delta) const { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED LLMemType m1(LLMemType::MTYPE_IO_BUFFER); const_segment_iterator_t it; const_segment_iterator_t end = mSegments.end(); @@ -709,9 +783,14 @@ U8* LLBufferArray::seek( return rv; } +//test use only bool LLBufferArray::takeContents(LLBufferArray& source) { LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + + LLMutexLock lock(mMutexp); + source.lock(); + std::copy( source.mBuffers.begin(), source.mBuffers.end(), @@ -723,13 +802,17 @@ bool LLBufferArray::takeContents(LLBufferArray& source) std::back_insert_iterator(mSegments)); source.mSegments.clear(); source.mNextBaseChannel = 0; + source.unlock(); + return true; } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::makeSegment( S32 channel, S32 len) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED LLMemType m1(LLMemType::MTYPE_IO_BUFFER); // start at the end of the buffers, because it is the most likely // to have free space. @@ -765,8 +848,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment( return send; } +//mMutexp should be locked before calling this. bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED LLMemType m1(LLMemType::MTYPE_IO_BUFFER); // Find out which buffer contains the segment, and if it is found, @@ -792,13 +877,14 @@ bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter) return rv; } - +//mMutexp should be locked before calling this. bool LLBufferArray::copyIntoBuffers( S32 channel, const U8* src, S32 len, std::vector& segments) { + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED LLMemType m1(LLMemType::MTYPE_IO_BUFFER); if(!src || !len) return false; S32 copied = 0; diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h index 1c42b6fbc6..ccdb9fa7ee 100644 --- a/indra/llmessage/llbuffer.h +++ b/indra/llmessage/llbuffer.h @@ -39,6 +39,7 @@ #include #include +class LLMutex; /** * @class LLChannelDescriptors * @brief A way simple interface to accesss channels inside a buffer @@ -564,6 +565,29 @@ public: * @return Returns true on success. */ bool eraseSegment(const segment_iterator_t& iter); + + /** + * @brief Lock the mutex if it exists + * This method locks mMutexp to make accessing LLBufferArray thread-safe + */ + void lock(); + + /** + * @brief Unlock the mutex if it exists + */ + void unlock(); + + /** + * @brief Return mMutexp + */ + LLMutex* getMutex(); + + /** + * @brief Set LLBufferArray to be shared across threads or not + * This method is to create mMutexp if is threaded. + * @param threaded Indicates this LLBufferArray instance is shared across threads if true. + */ + void setThreaded(bool threaded); //@} protected: @@ -595,6 +619,7 @@ protected: S32 mNextBaseChannel; buffer_list_t mBuffers; segment_list_t mSegments; + LLMutex* mMutexp; }; #endif // LL_LLBUFFER_H diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp index 6257983c43..8d8ad05ad5 100644 --- a/indra/llmessage/llbufferstream.cpp +++ b/indra/llmessage/llbufferstream.cpp @@ -31,6 +31,7 @@ #include "llbuffer.h" #include "llmemtype.h" +#include "llthread.h" static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4; @@ -62,6 +63,7 @@ int LLBufferStreamBuf::underflow() return EOF; } + LLMutexLock lock(mBuffer->getMutex()); LLBufferArray::segment_iterator_t iter; LLBufferArray::segment_iterator_t end = mBuffer->endSegment(); U8* last_pos = (U8*)gptr(); @@ -149,6 +151,7 @@ int LLBufferStreamBuf::overflow(int c) // since we got here, we have a buffer, and we have a character to // put on it. LLBufferArray::segment_iterator_t it; + LLMutexLock lock(mBuffer->getMutex()); it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE); if(it != mBuffer->endSegment()) { @@ -210,6 +213,7 @@ int LLBufferStreamBuf::sync() // *NOTE: I bet we could just --address if address is not NULL. // Need to think about that. + LLMutexLock lock(mBuffer->getMutex()); address = mBuffer->seek(mChannels.out(), address, -1); if(address) { @@ -273,6 +277,8 @@ streampos LLBufferStreamBuf::seekoff( // NULL is fine break; } + + LLMutexLock lock(mBuffer->getMutex()); address = mBuffer->seek(mChannels.in(), base_addr, off); if(address) { @@ -304,6 +310,8 @@ streampos LLBufferStreamBuf::seekoff( // NULL is fine break; } + + LLMutexLock lock(mBuffer->getMutex()); address = mBuffer->seek(mChannels.out(), base_addr, off); if(address) { diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 5edf0dc8c0..1ab82a273b 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -228,6 +228,8 @@ LLMutex* LLCurl::Easy::sHandleMutexp = NULL ; //static CURL* LLCurl::Easy::allocEasyHandle() { + llassert(LLCurl::getCurlThread()) ; + CURL* ret = NULL; LLMutexLock lock(sHandleMutexp) ; @@ -489,6 +491,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, LLProxy::getInstance()->applyProxySettings(this); mOutput.reset(new LLBufferArray); + mOutput->setThreaded(true); setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback); setopt(CURLOPT_WRITEDATA, (void*)this); diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 73e8a69085..987f386aa3 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -818,6 +818,8 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl( // Copy everything after mLast read to the out. LLBufferArray::segment_iterator_t seg_iter; + + buffer->lock(); seg_iter = buffer->splitAfter(mLastRead); if(seg_iter != buffer->endSegment()) { @@ -838,7 +840,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl( } #endif } - + buffer->unlock(); // // *FIX: get rid of extra bytes off the end // diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 54ceab3422..d5b4d45821 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -445,6 +445,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( // efficient - not only because writev() is better, but also // because we won't have to do as much work to find the start // address. + buffer->lock(); LLBufferArray::segment_iterator_t it; LLBufferArray::segment_iterator_t end = buffer->endSegment(); LLSegment segment; @@ -524,6 +525,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( } } + buffer->unlock(); + PUMP_DEBUG; if(done && eos) { diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 0ff300efd0..f3ef4f2684 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -207,6 +207,7 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request info.mHasCurlRequest = has_curl_request; info.setTimeoutSeconds(timeout); info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray); + info.mData->setThreaded(has_curl_request); LLLinkInfo link; #if LL_DEBUG_PIPE_TYPE_IN_PUMP lldebugs << "LLPumpIO::addChain() " << chain[0] << " '" -- cgit v1.3 From 1316f3313066beef74729c2be5a8d142d185161d Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 25 Jan 2012 16:01:56 -0700 Subject: fix for SH-2904: textures remain stuck in HTP state --- indra/llmessage/llcurl.cpp | 11 +++++++++++ indra/llmessage/llcurl.h | 2 ++ 2 files changed, 13 insertions(+) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 1ab82a273b..32a9cd061f 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -91,6 +91,7 @@ std::string LLCurl::sCAFile; LLCurlThread* LLCurl::sCurlThread = NULL ; LLMutex* LLCurl::sHandleMutexp = NULL ; S32 LLCurl::sTotalHandles = 0 ; +bool LLCurl::sNotQuitting = true; void check_curl_code(CURLcode code) { @@ -319,6 +320,14 @@ LLCurl::Easy::~Easy() --gCurlEasyCount; curl_slist_free_all(mHeaders); for_each(mStrings.begin(), mStrings.end(), DeletePointerArray()); + + if (mResponder && LLCurl::sNotQuitting) //aborted + { + std::string reason("Request timeout, aborted.") ; + mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort + reason, mChannels, mOutput); + } + mResponder = NULL; } void LLCurl::Easy::resetState() @@ -1462,6 +1471,8 @@ void LLCurl::initClass(bool multi_threaded) void LLCurl::cleanupClass() { + sNotQuitting = false; //set quitting + //shut down curl thread while(1) { diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 2b23ac9763..7d2340a6cb 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -197,6 +197,8 @@ private: static LLMutex* sHandleMutexp ; static S32 sTotalHandles ; +public: + static bool sNotQuitting; }; class LLCurl::Easy -- cgit v1.3 From 717a6f3306d9382ea252c3e0f243b785c9cae15a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 25 Jan 2012 18:27:40 -0700 Subject: Introduce two new parameters "CurlUseMultipleThreads" and "CurlRequestTimeOut" for QA to test Curl. --- indra/llmessage/llcurl.cpp | 18 ++++++++++-------- indra/llmessage/llcurl.h | 4 +++- indra/newview/app_settings/settings.xml | 22 ++++++++++++++++++++++ indra/newview/llappviewer.cpp | 4 +++- 4 files changed, 38 insertions(+), 10 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 32a9cd061f..3bcaffc275 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -75,9 +75,6 @@ static const S32 MULTI_PERFORM_CALL_REPEAT = 5; static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation static const S32 MAX_ACTIVE_REQUEST_COUNT = 100; -static const F32 DEFAULT_MULTI_IDLE_TIME = 120.0f ; //seconds -static const S32 MAX_NUM_OF_HANDLES = 256 ; //max number of handles, (multi handles and easy handles combined). - // DEBUG // S32 gCurlEasyCount = 0; S32 gCurlMultiCount = 0; @@ -92,6 +89,8 @@ LLCurlThread* LLCurl::sCurlThread = NULL ; LLMutex* LLCurl::sHandleMutexp = NULL ; S32 LLCurl::sTotalHandles = 0 ; bool LLCurl::sNotQuitting = true; +F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds +S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined). void check_curl_code(CURLcode code) { @@ -573,9 +572,9 @@ LLCurl::Multi::Multi(F32 idle_time_out) LLCurl::getCurlThread()->addMulti(this) ; mIdleTimeOut = idle_time_out ; - if(mIdleTimeOut < DEFAULT_MULTI_IDLE_TIME) + if(mIdleTimeOut < LLCurl::sCurlRequestTimeOut) { - mIdleTimeOut = DEFAULT_MULTI_IDLE_TIME ; + mIdleTimeOut = LLCurl::sCurlRequestTimeOut ; } ++gCurlMultiCount; @@ -1442,8 +1441,11 @@ unsigned long LLCurl::ssl_thread_id(void) } #endif -void LLCurl::initClass(bool multi_threaded) +void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool multi_threaded) { + sCurlRequestTimeOut = curl_reuest_timeout ; //seconds + sMaxHandles = max_number_handles ; //max number of handles, (multi handles and easy handles combined). + // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" // - http://curl.haxx.se/libcurl/c/curl_global_init.html @@ -1512,7 +1514,7 @@ CURLM* LLCurl::newMultiHandle() { LLMutexLock lock(sHandleMutexp) ; - if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES) + if(sTotalHandles + 1 > sMaxHandles) { llwarns << "no more handles available." << llendl ; return NULL ; //failed @@ -1545,7 +1547,7 @@ CURL* LLCurl::newEasyHandle() { LLMutexLock lock(sHandleMutexp) ; - if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES) + if(sTotalHandles + 1 > sMaxHandles) { llwarns << "no more handles available." << llendl ; return NULL ; //failed diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 7d2340a6cb..fd664c0fa1 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -163,7 +163,7 @@ public: /** * @ brief Initialize LLCurl class */ - static void initClass(bool multi_threaded = false); + static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false); /** * @ brief Cleanup LLCurl class @@ -197,8 +197,10 @@ private: static LLMutex* sHandleMutexp ; static S32 sTotalHandles ; + static S32 sMaxHandles; public: static bool sNotQuitting; + static F32 sCurlRequestTimeOut; }; class LLCurl::Easy diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1ea623791d..a29d5d2985 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1828,6 +1828,28 @@ Value 0 + CurlMaximumNumberOfHandles + + Comment + Maximum number of handles curl can use (requires restart) + Persist + 1 + Type + S32 + Value + 256 + + CurlRequestTimeOut + + Comment + Max idle time of a curl request before killed (requires restart) + Persist + 1 + Type + F32 + Value + 120.0 + CurlUseMultipleThreads Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 40136adbc9..4fc306e61d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -720,7 +720,9 @@ bool LLAppViewer::init() // *NOTE:Mani - LLCurl::initClass is not thread safe. // Called before threads are created. - LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads")); + LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"), + gSavedSettings.getS32("CurlMaximumNumberOfHandles"), + gSavedSettings.getBOOL("CurlUseMultipleThreads")); LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ; LLMachineID::init(); -- cgit v1.3 From 5a14a67e060e7f325025e924c83489cfa236e3dc Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 1 Feb 2012 13:03:46 -0800 Subject: converted a bunch of narrowing implicit conversions to explicit --- indra/llaudio/llaudiodecodemgr.cpp | 2 +- indra/llcommon/linden_common.h | 20 +++--------- indra/llcommon/llevents.cpp | 4 +-- indra/llcommon/llmd5.cpp | 2 +- indra/llcommon/llpreprocessor.h | 3 +- indra/llcommon/llsdserialize.cpp | 18 +++++----- indra/llcommon/llsdserialize_xml.cpp | 2 +- indra/llcommon/llsdutil.h | 2 +- indra/llcommon/llstat.cpp | 2 +- indra/llcommon/lltimer.cpp | 2 +- indra/llcrashlogger/llcrashlogger.cpp | 2 +- indra/llimage/llimagej2c.cpp | 8 ++--- indra/llinventory/llinventory.cpp | 4 +-- indra/llmath/llcalcparser.h | 2 +- indra/llmath/llvolume.cpp | 4 +-- indra/llmath/m4math.cpp | 38 +++++++++++----------- indra/llmessage/llbufferstream.cpp | 4 +-- indra/llmessage/llcurl.cpp | 4 +-- indra/llmessage/llhttpclient.cpp | 2 +- indra/llmessage/llmime.cpp | 4 +-- indra/llmessage/llsdmessage.cpp | 2 +- indra/llmessage/llsdmessagebuilder.cpp | 2 +- indra/llmessage/message.cpp | 6 ++-- indra/llrender/llfontgl.cpp | 26 +++++++-------- indra/llui/lldraghandle.cpp | 2 +- indra/llvfs/lllfsthread.cpp | 2 +- indra/llvfs/llvfsthread.cpp | 2 +- indra/llxml/llxmlnode.cpp | 2 +- .../quicktime/media_plugin_quicktime.cpp | 6 ++-- indra/media_plugins/webkit/media_plugin_webkit.cpp | 24 +++++++------- indra/newview/tests/llworldmipmap_test.cpp | 4 +-- .../viewer_components/updater/llupdaterservice.cpp | 2 +- 32 files changed, 99 insertions(+), 110 deletions(-) (limited to 'indra/llmessage/llcurl.cpp') diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index f0b44f97d2..7f747c2eca 100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -215,7 +215,7 @@ BOOL LLVorbisDecodeState::initDecode() return(FALSE); } - S32 sample_count = ov_pcm_total(&mVF, -1); + S32 sample_count = (S32)ov_pcm_total(&mVF, -1); size_t size_guess = (size_t)sample_count; vorbis_info* vi = ov_info(&mVF, -1); size_guess *= (vi? vi->channels : 1); diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index bdcc98e402..2e4885403e 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -52,24 +52,12 @@ #include #include -// Work around Microsoft compiler warnings in STL headers -#ifdef LL_WINDOWS -#pragma warning (disable : 4702) // unreachable code -#pragma warning (disable : 4244) // conversion from time_t to S32 -#endif // LL_WINDOWS - // *TODO: Eliminate these, most library .cpp files don't need them. // Add them to llviewerprecompiledheaders.h if necessary. -#include -#include -#include -#include - -#ifdef LL_WINDOWS -// Reenable warnings we disabled above -#pragma warning (3 : 4702) // unreachable code, we like level 3, not 4 -// moved msvc warnings to llpreprocessor.h *TODO - delete this comment after merge conflicts are unlikely -brad -#endif // LL_WINDOWS +//#include +//#include +//#include +//#include // Linden only libs in alpha-order other than stdtypes.h // *NOTE: Please keep includes here to a minimum, see above. diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index db1ea4792b..0855180dcd 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -430,13 +430,13 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL { // The new node isn't last. Place it between the previous node and // the successor. - newNode = (myprev + mydmi->second)/2.0; + newNode = (myprev + mydmi->second)/2.f; } else { // The new node is last. Bump myprev up to the next integer, add // 1.0 and use that. - newNode = std::ceil(myprev) + 1.0; + newNode = std::ceil(myprev) + 1.f; } // Now that newNode has a value that places it appropriately in mSignal, // connect it. diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 75fde8e5ba..1409c55d1c 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -175,7 +175,7 @@ void LLMD5::update(std::istream& stream){ while (stream.good()){ stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable. - len=stream.gcount(); + len=(int)stream.gcount(); update(buffer, len); } diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 31d5f3d2c7..7fdb537ab5 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -132,7 +132,7 @@ #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" #pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden #pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored -#pragma warning( disable : 4284 ) // silly MS warning deep inside their include file +//#pragma warning( disable : 4284 ) // silly MS warning deep inside their include file #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) #pragma warning( disable : 4996 ) // warning: deprecated @@ -152,6 +152,7 @@ #pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class #pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class #pragma warning (disable : 4018) // '<' : signed/unsigned mismatch + #endif // LL_MSVC #if LL_WINDOWS diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index bf62600514..b419101b7e 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -110,7 +110,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */ { legacy_no_header = true; - inbuf = str.gcount(); + inbuf = (int)str.gcount(); } else { @@ -343,7 +343,7 @@ std::istream& LLSDParser::get( char delim) const { istr.get(s, n, delim); - if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); return istr; } @@ -353,7 +353,7 @@ std::istream& LLSDParser::get( char delim) const { istr.get(sb, delim); - if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); return istr; } @@ -377,7 +377,7 @@ std::istream& LLSDParser::read( std::streamsize n) const { istr.read(s, n); - if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); return istr; } @@ -789,7 +789,7 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const if(len) { value.resize(len); - account(fullread(istr, (char *)&value[0], len)); + account((int)fullread(istr, (char *)&value[0], len)); } c = get(istr); // strip off the trailing double-quote data = value; @@ -1069,7 +1069,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const if(size > 0) { value.resize(size); - account(fullread(istr, (char*)&value[0], size)); + account((int)fullread(istr, (char*)&value[0], size)); } data = value; } @@ -1200,7 +1200,7 @@ bool LLSDBinaryParser::parseString( if(size) { buf.resize(size); - account(fullread(istr, &buf[0], size)); + account((int)fullread(istr, &buf[0], size)); value.assign(buf.begin(), buf.end()); } return true; @@ -1642,7 +1642,7 @@ int deserialize_string_raw( const S32 BUF_LEN = 20; char buf[BUF_LEN]; /* Flawfinder: ignore */ istr.get(buf, BUF_LEN - 1, ')'); - count += istr.gcount(); + count += (int)istr.gcount(); int c = istr.get(); c = istr.get(); count += 2; @@ -1657,7 +1657,7 @@ int deserialize_string_raw( if(len) { buf.resize(len); - count += fullread(istr, (char *)&buf[0], len); + count += (int)fullread(istr, (char *)&buf[0], len); value.assign(buf.begin(), buf.end()); } c = istr.get(); diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index be9db53906..34b3dbb99a 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -464,7 +464,7 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data) } } - status = XML_ParseBuffer(mParser, num_read, false); + status = XML_ParseBuffer(mParser, (int)num_read, false); if (status == XML_STATUS_ERROR) { break; diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 65c7297cbf..532d3f9341 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -308,7 +308,7 @@ class LLSDParam \ { \ public: \ LLSDParam(const LLSD& value): \ - _value(value.AS()) \ + _value((T)value.AS()) \ {} \ \ operator T() const { return _value; } \ diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index b2c495d093..057257057f 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -593,7 +593,7 @@ void LLStatTime::stop() { if ( LLStatAccum::SCALE_PER_FRAME == scale ) { - return mTotalTimeInFrame; + return (F32)mTotalTimeInFrame; } else { diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 38054b636e..9ebc6de7f4 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -83,7 +83,7 @@ U32 micro_sleep(U64 us, U32 max_yields) { // max_yields is unused; just fiddle with it to avoid warnings. max_yields = 0; - ms_sleep(us / 1000); + ms_sleep((U32)(us / 1000)); return 0; } #elif LL_LINUX || LL_SOLARIS || LL_DARWIN diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 3461aa3e6c..d6dcde4b9f 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -250,7 +250,7 @@ void LLCrashLogger::gatherFiles() if(minidump_stream.is_open()) { minidump_stream.seekg(0, std::ios::end); - size_t length = minidump_stream.tellg(); + size_t length = (size_t)minidump_stream.tellg(); minidump_stream.seekg(0, std::ios::beg); LLSD::Binary data; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index cc8cb66d73..8241746a74 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -501,10 +501,10 @@ void LLImageCompressionTester::outputTestRecord(LLSD *sd) F32 decompressionRate = 0.0f; F32 compressionRate = 0.0f; - F32 totalkBInDecompression = (F32)(mTotalBytesInDecompression) / 1000.0; - F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.0; - F32 totalkBInCompression = (F32)(mTotalBytesInCompression) / 1000.0; - F32 totalkBOutCompression = (F32)(mTotalBytesOutCompression) / 1000.0; + F32 totalkBInDecompression = (F32)(mTotalBytesInDecompression) / 1000.f; + F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.f; + F32 totalkBInCompression = (F32)(mTotalBytesInCompression) / 1000.f; + F32 totalkBOutCompression = (F32)(mTotalBytesOutCompression) / 1000.f; if (!is_approx_zero(mTotalTimeDecompression)) { diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 76760aa414..fbf23bc3f0 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -405,7 +405,7 @@ U32 LLInventoryItem::getCRC32() const //lldebugs << "7 crc: " << std::hex << crc << std::dec << llendl; crc += mSaleInfo.getCRC32(); //lldebugs << "8 crc: " << std::hex << crc << std::dec << llendl; - crc += mCreationDate; + crc += (U32)mCreationDate; //lldebugs << "9 crc: " << std::hex << crc << std::dec << llendl; return crc; } @@ -521,7 +521,7 @@ void LLInventoryItem::packMessage(LLMessageSystem* msg) const mSaleInfo.packMessage(msg); msg->addStringFast(_PREHASH_Name, mName); msg->addStringFast(_PREHASH_Description, mDescription); - msg->addS32Fast(_PREHASH_CreationDate, mCreationDate); + msg->addS32Fast(_PREHASH_CreationDate, (S32)mCreationDate); U32 crc = getCRC32(); msg->addU32Fast(_PREHASH_CRC, crc); } diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index bd9c8c2519..3509bd289b 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -174,7 +174,7 @@ private: F32 _log(const F32& a) const { return log(a); } F32 _exp(const F32& a) const { return exp(a); } F32 _fabs(const F32& a) const { return fabs(a); } - F32 _floor(const F32& a) const { return llfloor(a); } + F32 _floor(const F32& a) const { return (F3)llfloor(a); } F32 _ceil(const F32& a) const { return llceil(a); } F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0c6cf1dfae..f08657a75c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2903,7 +2903,7 @@ F32 LLVolume::sculptGetSurfaceArea() // compute the area of the quad by taking the length of the cross product of the two triangles LLVector3 cross1 = (p1 - p2) % (p1 - p3); LLVector3 cross2 = (p4 - p2) % (p4 - p3); - area += (cross1.magVec() + cross2.magVec()) / 2.0; + area += (cross1.magVec() + cross2.magVec()) / 2.f; } } @@ -5887,7 +5887,7 @@ F32 find_vertex_score(LLVCacheVertexData& data) } //bonus points for having low valence - F32 valence_boost = powf(data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); + F32 valence_boost = powf((F32)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); score += FindVertexScore_ValenceBoostScale * valence_boost; return score; diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index bad4deb4de..6a1b4143cf 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -858,25 +858,25 @@ LLSD LLMatrix4::getValue() const void LLMatrix4::setValue(const LLSD& data) { - mMatrix[0][0] = data[0].asReal(); - mMatrix[0][1] = data[1].asReal(); - mMatrix[0][2] = data[2].asReal(); - mMatrix[0][3] = data[3].asReal(); - - mMatrix[1][0] = data[4].asReal(); - mMatrix[1][1] = data[5].asReal(); - mMatrix[1][2] = data[6].asReal(); - mMatrix[1][3] = data[7].asReal(); - - mMatrix[2][0] = data[8].asReal(); - mMatrix[2][1] = data[9].asReal(); - mMatrix[2][2] = data[10].asReal(); - mMatrix[2][3] = data[11].asReal(); - - mMatrix[3][0] = data[12].asReal(); - mMatrix[3][1] = data[13].asReal(); - mMatrix[3][2] = data[14].asReal(); - mMatrix[3][3] = data[15].asReal(); + mMatrix[0][0] = (F32)data[0].asReal(); + mMatrix[0][1] = (F32)data[1].asReal(); + mMatrix[0][2] = (F32)data[2].asReal(); + mMatrix[0][3] = (F32)data[3].asReal(); + + mMatrix[1][0] = (F32)data[4].asReal(); + mMatrix[1][1] = (F32)data[5].asReal(); + mMatrix[1][2] = (F32)data[6].asReal(); + mMatrix[1][3] = (F32)data[7].asReal(); + + mMatrix[2][0] = (F32)data[8].asReal(); + mMatrix[2][1] = (F32)data[9].asReal(); + mMatrix[2][2] = (F32)data[10].asReal(); + mMatrix[2][3] = (F32)data[11].asReal(); + + mMatrix[3][0] = (F32)data[12].asReal(); + mMatrix[3][1] = (F32)data[13].asReal(); + mMatrix[3][2] = (F32)data[14].asReal(); + mMatrix[3][3] = (F32)data[15].asReal(); } diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp index 6257983c43..bb65d16670 100644 --- a/indra/llmessage/llbufferstream.cpp +++ b/indra/llmessage/llbufferstream.cpp @@ -273,7 +273,7 @@ streampos LLBufferStreamBuf::seekoff( // NULL is fine break; } - address = mBuffer->seek(mChannels.in(), base_addr, off); + address = (S32)mBuffer->seek(mChannels.in(), base_addr, off); if(address) { LLBufferArray::segment_iterator_t iter; @@ -304,7 +304,7 @@ streampos LLBufferStreamBuf::seekoff( // NULL is fine break; } - address = mBuffer->seek(mChannels.out(), base_addr, off); + address = (S32)mBuffer->seek(mChannels.out(), base_addr, off); if(address) { LLBufferArray::segment_iterator_t iter; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index e17380fdf5..344463f036 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -428,9 +428,9 @@ size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data) LLCurl::Easy* easy = (LLCurl::Easy*)user_data; S32 n = size * nmemb; - S32 startpos = easy->getInput().tellg(); + S32 startpos = (S32)easy->getInput().tellg(); easy->getInput().seekg(0, std::ios::end); - S32 endpos = easy->getInput().tellg(); + S32 endpos = (S32)easy->getInput().tellg(); easy->getInput().seekg(startpos, std::ios::beg); S32 maxn = endpos - startpos; n = llmin(n, maxn); diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index dd4e3a6300..98983ad28a 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -158,7 +158,7 @@ namespace if(fstream.is_open()) { fstream.seekg(0, std::ios::end); - U32 fileSize = fstream.tellg(); + U32 fileSize = (U32)fstream.tellg(); fstream.seekg(0, std::ios::beg); std::vector fileBuffer(fileSize); fstream.read(&fileBuffer[0], fileSize); diff --git a/indra/llmessage/llmime.cpp b/indra/llmessage/llmime.cpp index 943a734927..9d9c4ebd68 100644 --- a/indra/llmessage/llmime.cpp +++ b/indra/llmessage/llmime.cpp @@ -388,7 +388,7 @@ bool LLMimeParser::Impl::parseHeaders( // not to read past limit when we get() the newline. S32 max_get = llmin((S32)LINE_BUFFER_LENGTH, limit - mScanCount - 1); istr.getline(mBuffer, max_get, '\r'); - mScanCount += istr.gcount(); + mScanCount += (S32)istr.gcount(); int c = istr.get(); if(EOF == c) { @@ -496,7 +496,7 @@ void LLMimeParser::Impl::scanPastSeparator( // past limit when we get() the newline. S32 max_get = llmin((S32)LINE_BUFFER_LENGTH, limit - mScanCount - 1); istr.getline(mBuffer, max_get, '\r'); - mScanCount += istr.gcount(); + mScanCount += (S32)istr.gcount(); if(istr.gcount() >= LINE_BUFFER_LENGTH - 1) { // that's way too long to be a separator, so ignore it. diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp index 9148c9dd15..1c93c12d99 100644 --- a/indra/llmessage/llsdmessage.cpp +++ b/indra/llmessage/llsdmessage.cpp @@ -88,7 +88,7 @@ bool LLSDMessage::httpListener(const LLSD& request) request, url, "POST", reply, error), LLSD(), // headers - timeout); + (F32)timeout); return false; } diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp index 2698a271ee..615221e0ad 100644 --- a/indra/llmessage/llsdmessagebuilder.cpp +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -317,7 +317,7 @@ void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data) // S64 not supported in LLSD so we just truncate it case MVT_S64: - addS32(varname, *(S64*)mvci.getData()); + addS32(varname, (S32)*(S64*)mvci.getData()); break; case MVT_F32: diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index d0b0e178b8..6a425cfe98 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -3147,7 +3147,7 @@ bool LLMessageSystem::generateDigestForWindowAndUUIDs(char* digest, const S32 wi LL_ERRS("Messaging") << "Trying to generate complex digest on a machine without a shared secret!" << llendl; } - U32 now = time(NULL); + U32 now = (U32)time(NULL); now /= window; @@ -3167,7 +3167,7 @@ bool LLMessageSystem::isMatchingDigestForWindowAndUUIDs(const char* digest, cons } char our_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ - U32 now = time(NULL); + U32 now = (U32)time(NULL); now /= window; @@ -3213,7 +3213,7 @@ bool LLMessageSystem::generateDigestForWindow(char* digest, const S32 window) co LL_ERRS("Messaging") << "Trying to generate simple digest on a machine without a shared secret!" << llendl; } - U32 now = time(NULL); + U32 now = (U32)time(NULL); now /= window; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 4eb10b2c93..4519c5e789 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -115,23 +115,23 @@ static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts"); S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const { - F32 x = rect.mLeft; + F32 x = (F32)rect.mLeft; F32 y = 0.f; switch(valign) { case TOP: - y = rect.mTop; + y = (F32)rect.mTop; break; case VCENTER: - y = rect.getCenterY(); + y = (F32)rect.getCenterY(); break; case BASELINE: case BOTTOM: - y = rect.mBottom; + y = (F32)rect.mBottom; break; default: - y = rect.mBottom; + y = (F32)rect.mBottom; break; } return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses); @@ -251,7 +251,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons cur_render_y = cur_y; cur_render_x = cur_x; - F32 start_x = llround(cur_x); + F32 start_x = (F32)llround(cur_x); const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); @@ -335,10 +335,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons (fgi->mXBitmapOffset + fgi->mWidth) * inv_width, (fgi->mYBitmapOffset - PAD_UVY) * inv_height); // snap glyph origin to whole screen pixel - LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing), - llround(cur_render_y + (F32)fgi->mYBearing), - llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, - llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); + LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing), + (F32)llround(cur_render_y + (F32)fgi->mYBearing), + (F32)llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, + (F32)llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); if (glyph_count >= GLYPH_BATCH_SIZE) { @@ -636,7 +636,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch } // Round after kerning. - cur_x = llround(cur_x); + cur_x = (F32)llround(cur_x); drawn_x = cur_x; } @@ -707,7 +707,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ } // Round after kerning. - total_width = llround(total_width); + total_width = (F32)llround(total_width); } if (drawable_chars == 0) @@ -790,7 +790,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t // Round after kerning. - cur_x = llround(cur_x); + cur_x = (F32)llround(cur_x); } return llmin(max_chars, pos - begin_offset); diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 5f69c6af31..42e6c3c786 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -244,7 +244,7 @@ void LLDragHandleTop::reshapeTitleBox() const LLFontGL* font = LLFontGL::getFontSansSerif(); S32 title_width = getRect().getWidth(); title_width -= LEFT_PAD + 2 * BORDER_PAD + getButtonsRect().getWidth(); - S32 title_height = font->getLineHeight(); + S32 title_height = llround(font->getLineHeight()); LLRect title_rect; title_rect.setLeftTopAndSize( LEFT_PAD, diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp index 3d3ed9f6d4..073b1af2a1 100644 --- a/indra/llvfs/lllfsthread.cpp +++ b/indra/llvfs/lllfsthread.cpp @@ -45,7 +45,7 @@ void LLLFSThread::initClass(bool local_is_threaded) //static S32 LLLFSThread::updateClass(U32 ms_elapsed) { - sLocal->update(ms_elapsed); + sLocal->update((F32)ms_elapsed); return sLocal->getPending(); } diff --git a/indra/llvfs/llvfsthread.cpp b/indra/llvfs/llvfsthread.cpp index 254f8b55ba..a57e2b15ab 100644 --- a/indra/llvfs/llvfsthread.cpp +++ b/indra/llvfs/llvfsthread.cpp @@ -46,7 +46,7 @@ void LLVFSThread::initClass(bool local_is_threaded) //static S32 LLVFSThread::updateClass(U32 ms_elapsed) { - sLocal->update(ms_elapsed); + sLocal->update((F32)ms_elapsed); return sLocal->getPending(); } diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 3d4e6f9a0b..2ffb0d8503 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -801,7 +801,7 @@ bool LLXMLNode::parseStream( while(str.good()) { str.read((char*)buffer, BUFSIZE); - int count = str.gcount(); + int count = (int)str.gcount(); if (XML_Parse(my_parser, (const char *)buffer, count, !str.good()) != XML_STATUS_OK) { diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 999f754dcf..24328202cb 100644 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -705,7 +705,7 @@ private: // look up "Display Name" in meta data OSType meta_data_key = kQTMetaDataCommonKeyDisplayName; QTMetaDataItem item = kQTMetaDataItemUninitialized; - result = QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard, + result = (OSErr)QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard, 0, kQTMetaDataKeyFormatCommon, (const UInt8 *)&meta_data_key, sizeof( meta_data_key ), &item ); @@ -714,14 +714,14 @@ private: // find the size of the title ByteCount size; - result = QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size ); + result = (OSErr)QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size ); if ( noErr != result || size <= 0 /*|| size > 1024 FIXME: arbitrary limit */ ) return false; // allocate some space and grab it UInt8* item_data = new UInt8[ size + 1 ]; memset( item_data, 0, ( size + 1 ) * sizeof( UInt8 ) ); - result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); + result = (OSErr)QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); if ( noErr != result ) { delete [] item_data; diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 47f8dcd545..1812abd7d5 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -991,7 +991,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) { if(message_name == "set_volume") { - F32 volume = message_in.getValueReal("volume"); + F32 volume = (F32)message_in.getValueReal("volume"); setVolume(volume); } } @@ -1057,9 +1057,9 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) S32 height = message_in.getValueS32("height"); S32 texture_width = message_in.getValueS32("texture_width"); S32 texture_height = message_in.getValueS32("texture_height"); - mBackgroundR = message_in.getValueReal("background_r"); - mBackgroundG = message_in.getValueReal("background_g"); - mBackgroundB = message_in.getValueReal("background_b"); + mBackgroundR = (F32)message_in.getValueReal("background_r"); + mBackgroundG = (F32)message_in.getValueReal("background_g"); + mBackgroundB = (F32)message_in.getValueReal("background_b"); // mBackgroundA = message_in.setValueReal("background_a"); // Ignore any alpha if(!name.empty()) @@ -1245,9 +1245,9 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) if(message_name == "js_agent_location") { #if LLQTWEBKIT_API_VERSION >= 9 - F32 x = message_in.getValueReal("x"); - F32 y = message_in.getValueReal("y"); - F32 z = message_in.getValueReal("z"); + F32 x = (F32)message_in.getValueReal("x"); + F32 y = (F32)message_in.getValueReal("y"); + F32 z = (F32)message_in.getValueReal("z"); LLQtWebKit::getInstance()->setAgentLocation( x, y, z ); LLQtWebKit::getInstance()->emitLocation(); #endif @@ -1256,9 +1256,9 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) if(message_name == "js_agent_global_location") { #if LLQTWEBKIT_API_VERSION >= 9 - F32 x = message_in.getValueReal("x"); - F32 y = message_in.getValueReal("y"); - F32 z = message_in.getValueReal("z"); + F32 x = (F32)message_in.getValueReal("x"); + F32 y = (F32)message_in.getValueReal("y"); + F32 z = (F32)message_in.getValueReal("z"); LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z ); LLQtWebKit::getInstance()->emitLocation(); #endif @@ -1267,7 +1267,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) if(message_name == "js_agent_orientation") { #if LLQTWEBKIT_API_VERSION >= 9 - F32 angle = message_in.getValueReal("angle"); + F32 angle = (F32)message_in.getValueReal("angle"); LLQtWebKit::getInstance()->setAgentOrientation( angle ); LLQtWebKit::getInstance()->emitLocation(); #endif @@ -1323,7 +1323,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) else if(message_name == "set_page_zoom_factor") { #if LLQTWEBKIT_API_VERSION >= 15 - F32 factor = message_in.getValueReal("factor"); + F32 factor = (F32)message_in.getValueReal("factor"); LLQtWebKit::getInstance()->setPageZoomFactor(factor); #else llwarns << "Ignoring setPageZoomFactor message (llqtwebkit version is too old)." << llendl; diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp index 4c0959d1a9..e7ef017760 100644 --- a/indra/newview/tests/llworldmipmap_test.cpp +++ b/indra/newview/tests/llworldmipmap_test.cpp @@ -100,9 +100,9 @@ namespace tut { S32 level = mMap->scaleToLevel(0.0); ensure("scaleToLevel() test 1 failed", level == LLWorldMipmap::MAP_LEVELS); - level = mMap->scaleToLevel(LLWorldMipmap::MAP_TILE_SIZE); + level = mMap->scaleToLevel((F32)LLWorldMipmap::MAP_TILE_SIZE); ensure("scaleToLevel() test 2 failed", level == 1); - level = mMap->scaleToLevel(10 * LLWorldMipmap::MAP_TILE_SIZE); + level = mMap->scaleToLevel(10.f * LLWorldMipmap::MAP_TILE_SIZE); ensure("scaleToLevel() test 3 failed", level == 1); } // Test 2 : globalToMipmap() diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 1888f191e2..2e18218667 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -447,7 +447,7 @@ void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) LL_INFOS("UpdaterService") << "will check for update again in " << seconds << " seconds" << LL_ENDL; mTimer.start(); - mTimer.setTimerExpirySec(seconds); + mTimer.setTimerExpirySec((F32)seconds); LLEventPumps::instance().obtain("mainloop").listen( sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); } -- cgit v1.3