diff options
Diffstat (limited to 'indra/llmessage')
-rw-r--r-- | indra/llmessage/llassetstorage.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/llcurl.cpp | 134 | ||||
-rw-r--r-- | indra/llmessage/llcurl.h | 3 | ||||
-rw-r--r-- | indra/llmessage/llhttpclient.cpp | 1 | ||||
-rw-r--r-- | indra/llmessage/llpumpio.cpp | 7 | ||||
-rw-r--r-- | indra/llmessage/lltransfermanager.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/lltransfersourceasset.cpp | 2 |
7 files changed, 141 insertions, 10 deletions
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 0ab1081200..047b99c861 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -505,7 +505,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at tpvf.setAsset(uuid, atype); tpvf.setCallback(downloadCompleteCallback, req); - llinfos << "Starting transfer for " << uuid << llendl; + //llinfos << "Starting transfer for " << uuid << llendl; LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f)); } diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 024e17a777..f8a7eb0417 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -55,6 +55,7 @@ #include "llstl.h" #include "llsdserialize.h" #include "llthread.h" +#include "lltimer.h" ////////////////////////////////////////////////////////////////////////////// /* @@ -256,7 +257,12 @@ public: void resetState(); + static CURL* allocEasyHandle(); + static void releaseEasyHandle(CURL* handle); + private: + friend class LLCurl; + CURL* mCurlEasyHandle; struct curl_slist* mHeaders; @@ -271,8 +277,62 @@ private: std::vector<char*> mStrings; ResponderPtr mResponder; + + static std::set<CURL*> sFreeHandles; + static std::set<CURL*> sActiveHandles; + static LLMutex* sHandleMutex; }; +std::set<CURL*> LLCurl::Easy::sFreeHandles; +std::set<CURL*> LLCurl::Easy::sActiveHandles; +LLMutex* LLCurl::Easy::sHandleMutex = NULL; + + +//static +CURL* LLCurl::Easy::allocEasyHandle() +{ + CURL* ret = NULL; + LLMutexLock lock(sHandleMutex); + if (sFreeHandles.empty()) + { + ret = curl_easy_init(); + } + else + { + ret = *(sFreeHandles.begin()); + sFreeHandles.erase(ret); + curl_easy_reset(ret); + } + + if (ret) + { + sActiveHandles.insert(ret); + } + + return ret; +} + +//static +void LLCurl::Easy::releaseEasyHandle(CURL* handle) +{ + if (!handle) + { + llerrs << "handle cannot be NULL!" << llendl; + } + + LLMutexLock lock(sHandleMutex); + + if (sActiveHandles.find(handle) != sActiveHandles.end()) + { + sActiveHandles.erase(handle); + sFreeHandles.insert(handle); + } + else + { + llerrs << "Invalid handle." << llendl; + } +} + LLCurl::Easy::Easy() : mHeaders(NULL), mCurlEasyHandle(NULL) @@ -283,25 +343,27 @@ LLCurl::Easy::Easy() LLCurl::Easy* LLCurl::Easy::getEasy() { Easy* easy = new Easy(); - easy->mCurlEasyHandle = curl_easy_init(); + easy->mCurlEasyHandle = allocEasyHandle(); + if (!easy->mCurlEasyHandle) { // this can happen if we have too many open files (fails in c-ares/ares_init.c) - llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; + llwarns << "allocEasyHandle() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; delete easy; return NULL; } - // set no DMS caching as default for all easy handles. This prevents them adopting a + // set no DNS caching as default for all easy handles. This prevents them adopting a // multi handles cache if they are added to one. curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); + ++gCurlEasyCount; return easy; } LLCurl::Easy::~Easy() { - curl_easy_cleanup(mCurlEasyHandle); + releaseEasyHandle(mCurlEasyHandle); --gCurlEasyCount; curl_slist_free_all(mHeaders); for_each(mStrings.begin(), mStrings.end(), DeletePointerArray()); @@ -379,6 +441,7 @@ U32 LLCurl::Easy::report(CURLcode code) { responseCode = 499; responseReason = strerror(code) + " : " + mErrorBuffer; + setopt(CURLOPT_FRESH_CONNECT, TRUE); } if (mResponder) @@ -465,7 +528,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, if (post) setoptString(CURLOPT_ENCODING, ""); -// setopt(CURLOPT_VERBOSE, 1); // usefull for debugging + //setopt(CURLOPT_VERBOSE, 1); // usefull for debugging setopt(CURLOPT_NOSIGNAL, 1); mOutput.reset(new LLBufferArray); @@ -482,7 +545,10 @@ void LLCurl::Easy::prepRequest(const std::string& url, setCA(); setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify()); - setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify()? 2 : 0); + //setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify()? 2 : 0); + + //don't verify host name so urls with scrubbed host names will work (improves DNS performance) + setopt(CURLOPT_SSL_VERIFYHOST, 0); setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); setoptString(CURLOPT_URL, url); @@ -543,6 +609,7 @@ LLCurl::Multi::Multi() mErrorCount(0) { mCurlMultiHandle = curl_multi_init(); + if (!mCurlMultiHandle) { llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; @@ -710,6 +777,7 @@ LLCurlRequest::LLCurlRequest() : mActiveRequestCount(0) { mThreadID = LLThread::currentID(); + mProcessing = FALSE; } LLCurlRequest::~LLCurlRequest() @@ -744,6 +812,11 @@ LLCurl::Easy* LLCurlRequest::allocEasy() bool LLCurlRequest::addEasy(LLCurl::Easy* easy) { llassert_always(mActiveMulti); + + if (mProcessing) + { + llerrs << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << llendl; + } bool res = mActiveMulti->addEasy(easy); return res; } @@ -801,12 +874,41 @@ bool LLCurlRequest::post(const std::string& url, bool res = addEasy(easy); return res; } + +bool LLCurlRequest::post(const std::string& url, + const headers_t& headers, + const std::string& data, + LLCurl::ResponderPtr responder) +{ + LLCurl::Easy* easy = allocEasy(); + if (!easy) + { + return false; + } + easy->prepRequest(url, headers, responder); + + easy->getInput().write(data.data(), data.size()); + S32 bytes = easy->getInput().str().length(); + easy->setopt(CURLOPT_POST, 1); + easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL); + easy->setopt(CURLOPT_POSTFIELDSIZE, bytes); + + easy->slist_append("Content-Type: application/octet-stream"); + easy->setHeaders(); + + lldebugs << "POSTING: " << bytes << " bytes." << llendl; + bool res = addEasy(easy); + return res; +} + // Note: call once per frame S32 LLCurlRequest::process() { llassert_always(mThreadID == LLThread::currentID()); S32 res = 0; + + mProcessing = TRUE; for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ) { @@ -820,6 +922,7 @@ S32 LLCurlRequest::process() delete multi; } } + mProcessing = FALSE; return res; } @@ -1042,6 +1145,8 @@ void LLCurl::initClass() // - http://curl.haxx.se/libcurl/c/curl_global_init.html curl_global_init(CURL_GLOBAL_ALL); + Easy::sHandleMutex = new LLMutex(NULL); + #if SAFE_SSL S32 mutex_count = CRYPTO_num_locks(); for (S32 i=0; i<mutex_count; i++) @@ -1059,5 +1164,22 @@ void LLCurl::cleanupClass() CRYPTO_set_locking_callback(NULL); for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer()); #endif + + delete Easy::sHandleMutex; + Easy::sHandleMutex = NULL; + + for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) + { + CURL* curl = *iter; + curl_easy_cleanup(curl); + } + + Easy::sFreeHandles.clear(); + + if (!Easy::sActiveHandles.empty()) + { + llerrs << "CURL easy handles not cleaned up on shutdown!" << llendl; + } + curl_global_cleanup(); } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index caf02cccd9..6ec0a5d8a7 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -213,6 +213,8 @@ public: void get(const std::string& url, LLCurl::ResponderPtr responder); bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); + S32 process(); S32 getQueued(); @@ -226,6 +228,7 @@ private: curlmulti_set_t mMultiSet; LLCurl::Multi* mActiveMulti; S32 mActiveRequestCount; + BOOL mProcessing; U32 mThreadID; // debug }; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index dd56e18caf..46952fa434 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -194,6 +194,7 @@ namespace fileBuffer = new U8 [fileSize]; vfile.read(fileBuffer, fileSize); ostream.write((char*)fileBuffer, fileSize); + delete [] fileBuffer; eos = true; return STATUS_DONE; } diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 5e9dfd81fa..e3ce2c5ad3 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -444,13 +444,13 @@ void LLPumpIO::pump() pump(DEFAULT_POLL_TIMEOUT); } -static LLFastTimer::DeclareTimer FTM_PUMP("Pump"); +static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO"); //timeout is in microseconds void LLPumpIO::pump(const S32& poll_timeout) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); - LLFastTimer t1(FTM_PUMP); + LLFastTimer t1(FTM_PUMP_IO); //llinfos << "LLPumpIO::pump()" << llendl; // Run any pending runners. @@ -778,6 +778,8 @@ bool LLPumpIO::respond( return true; } +static LLFastTimer::DeclareTimer FTM_PUMP_CALLBACK_CHAIN("Chain"); + void LLPumpIO::callback() { LLMemType m1(LLMemType::MTYPE_IO_PUMP); @@ -799,6 +801,7 @@ void LLPumpIO::callback() callbacks_t::iterator end = mCallbacks.end(); for(; it != end; ++it) { + LLFastTimer t(FTM_PUMP_CALLBACK_CHAIN); // it's always the first and last time for respone chains (*it).mHead = (*it).mChainLinks.begin(); (*it).mInit = true; diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp index d64b666ede..de9c609500 100644 --- a/indra/llmessage/lltransfermanager.cpp +++ b/indra/llmessage/lltransfermanager.cpp @@ -344,7 +344,7 @@ void LLTransferManager::processTransferInfo(LLMessageSystem *msgp, void **) } } - llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl; + //llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl; ttp->setSize(size); ttp->setGotInfo(TRUE); diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp index 8f36d516d7..7a27f01ea3 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -273,6 +273,7 @@ bool is_asset_fetch_by_id_allowed(LLAssetType::EType type) case LLAssetType::AT_BODYPART: case LLAssetType::AT_ANIMATION: case LLAssetType::AT_GESTURE: + case LLAssetType::AT_MESH: rv = true; break; default: @@ -297,6 +298,7 @@ bool is_asset_id_knowable(LLAssetType::EType type) case LLAssetType::AT_GESTURE: case LLAssetType::AT_LINK: case LLAssetType::AT_LINK_FOLDER: + case LLAssetType::AT_MESH: rv = true; break; default: |