diff options
Diffstat (limited to 'indra/llmessage')
| -rw-r--r-- | indra/llmessage/llassetstorage.cpp | 2 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.cpp | 135 | ||||
| -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 | 1 | 
7 files changed, 140 insertions, 11 deletions
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 20d71c6903..2494ab2792 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -543,7 +543,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..5caf620059 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,21 @@ void LLCurl::cleanupClass()  	CRYPTO_set_locking_callback(NULL);  	for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());  #endif -	curl_global_cleanup(); + +	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; +	}  } + 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 43f7c07e94..8c0520687a 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -257,3 +257,4 @@ BOOL LLTransferSourceParamsAsset::unpackParams(LLDataPacker &dp)  	return TRUE;  } +  | 
