diff options
author | Merov Linden <merov@lindenlab.com> | 2012-06-08 18:58:35 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2012-06-08 18:58:35 -0700 |
commit | 1bfdfcb7b9dd392459b012b0712237716c94a84c (patch) | |
tree | bdc4dfb4ef49c209acbdc3e9dd633a5a8a29dbba /indra/llmessage/llcurl.cpp | |
parent | ab954444154de43ee18575a3b0649d0f3045dfd8 (diff) | |
parent | dab5ef9d881bc41bc4924102c939db25dd26e0d9 (diff) |
Merge pull from vir/drano
Diffstat (limited to 'indra/llmessage/llcurl.cpp')
-rw-r--r-- | indra/llmessage/llcurl.cpp | 268 |
1 files changed, 239 insertions, 29 deletions
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 3bcaffc275..4cfa48cbd9 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -271,10 +271,10 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle) if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES) { - sFreeHandles.insert(handle); - } - else - { + sFreeHandles.insert(handle); + } + else + { LLCurl::deleteEasyHandle(handle) ; } } @@ -453,9 +453,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); @@ -560,16 +560,16 @@ LLCurl::Multi::Multi(F32 idle_time_out) } //llassert_always(mCurlMultiHandle); - + if(mCurlMultiHandle) { - if(LLCurl::getCurlThread()->getThreaded()) - { - 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 < LLCurl::sCurlRequestTimeOut) @@ -577,8 +577,8 @@ LLCurl::Multi::Multi(F32 idle_time_out) mIdleTimeOut = LLCurl::sCurlRequestTimeOut ; } - ++gCurlMultiCount; - } + ++gCurlMultiCount; +} } LLCurl::Multi::~Multi() @@ -617,7 +617,7 @@ void LLCurl::Multi::cleanup() mDeletionMutexp = NULL ; delete mEasyMutexp ; mEasyMutexp = NULL ; - + mQueued = 0 ; mState = STATE_COMPLETED; @@ -738,7 +738,7 @@ 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. @@ -1033,7 +1033,7 @@ void LLCurlRequest::addMulti() mActiveRequestCount = 0 ; return; } - + mMultiSet.insert(multi); mActiveMulti = multi; mActiveRequestCount = 0; @@ -1074,7 +1074,9 @@ void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder) { getByteRange(url, headers_t(), 0, -1, responder); } - + +// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or +// the remainder of the file if not. bool LLCurlRequest::getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, @@ -1092,6 +1094,11 @@ bool LLCurlRequest::getByteRange(const std::string& url, std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1); easy->slist_append(range.c_str()); } + else if (offset > 0) + { + std::string range = llformat("Range: bytes=%d-", offset); + easy->slist_append(range.c_str()); + } easy->setHeaders(); bool res = addEasy(easy); return res; @@ -1217,6 +1224,208 @@ S32 LLCurlRequest::getQueued() return queued; } +LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) : + LLCurlRequest(), + mConcurrency(concurrency), + mInQueue(0), + mMutex(NULL), + mHandleCounter(1), + mTotalIssuedRequests(0), + mTotalReceivedBits(0) +{ + mGlobalTimer.reset(); +} + +LLCurlTextureRequest::~LLCurlTextureRequest() +{ + mRequestMap.clear(); + + for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter) + { + delete *iter; + } + mCachedRequests.clear(); +} + +//return 0: success +// > 0: cached handle +U32 LLCurlTextureRequest::getByteRange(const std::string& url, + const headers_t& headers, + S32 offset, S32 length, U32 pri, + LLCurl::ResponderPtr responder, F32 delay_time) +{ + U32 ret_val = 0; + bool success = false; + + if(mInQueue < mConcurrency && delay_time < 0.f) + { + success = LLCurlRequest::getByteRange(url, headers, offset, length, responder); + } + + LLMutexLock lock(&mMutex); + + if(success) + { + mInQueue++; + mTotalIssuedRequests++; + } + else + { + request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder); + if(delay_time > 0.f) + { + request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time; + } + + mCachedRequests.insert(request); + mRequestMap[mHandleCounter] = request; + ret_val = mHandleCounter; + mHandleCounter++; + + if(!mHandleCounter) + { + mHandleCounter = 1; + } + } + + return ret_val; +} + +void LLCurlTextureRequest::completeRequest(S32 received_bytes) +{ + LLMutexLock lock(&mMutex); + + llassert_always(mInQueue > 0); + + mInQueue--; + mTotalReceivedBits += received_bytes * 8; +} + +void LLCurlTextureRequest::nextRequests() +{ + if(mCachedRequests.empty() || mInQueue >= mConcurrency) + { + return; + } + + F32 cur_time = mGlobalTimer.getElapsedTimeF32(); + + req_queue_t::iterator iter; + { + LLMutexLock lock(&mMutex); + iter = mCachedRequests.begin(); + } + while(1) + { + request_t* request = *iter; + if(request->mStartTime < cur_time) + { + if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder)) + { + break; + } + + LLMutexLock lock(&mMutex); + ++iter; + mInQueue++; + mTotalIssuedRequests++; + mCachedRequests.erase(request); + mRequestMap.erase(request->mHandle); + delete request; + + if(iter == mCachedRequests.end() || mInQueue >= mConcurrency) + { + break; + } + } + else + { + LLMutexLock lock(&mMutex); + ++iter; + if(iter == mCachedRequests.end() || mInQueue >= mConcurrency) + { + break; + } + } + } + + return; +} + +void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri) +{ + if(!handle) + { + return; + } + + LLMutexLock lock(&mMutex); + + std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle); + if(iter != mRequestMap.end()) + { + request_t* req = iter->second; + + if(req->mPriority != pri) + { + mCachedRequests.erase(req); + req->mPriority = pri; + mCachedRequests.insert(req); + } + } +} + +void LLCurlTextureRequest::removeRequest(U32 handle) +{ + if(!handle) + { + return; + } + + LLMutexLock lock(&mMutex); + + std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle); + if(iter != mRequestMap.end()) + { + request_t* req = iter->second; + mRequestMap.erase(iter); + mCachedRequests.erase(req); + delete req; + } +} + +bool LLCurlTextureRequest::isWaiting(U32 handle) +{ + if(!handle) + { + return false; + } + + LLMutexLock lock(&mMutex); + return mRequestMap.find(handle) != mRequestMap.end(); +} + +U32 LLCurlTextureRequest::getTotalReceivedBits() +{ + LLMutexLock lock(&mMutex); + + U32 bits = mTotalReceivedBits; + mTotalReceivedBits = 0; + return bits; +} + +U32 LLCurlTextureRequest::getTotalIssuedRequests() +{ + LLMutexLock lock(&mMutex); + return mTotalIssuedRequests; +} + +S32 LLCurlTextureRequest::getNumRequests() +{ + LLMutexLock lock(&mMutex); + return mInQueue; +} + //////////////////////////////////////////////////////////////////////////// // For generating one easy request // associated with a single multi request @@ -1229,15 +1438,15 @@ LLCurlEasyRequest::LLCurlEasyRequest() if(mMulti->isValid()) { - mEasy = mMulti->allocEasy(); - if (mEasy) - { - 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) ; @@ -1506,7 +1715,8 @@ void LLCurl::cleanupClass() delete sHandleMutexp ; sHandleMutexp = NULL ; - llassert(Easy::sActiveHandles.empty()); + // removed as per https://jira.secondlife.com/browse/SH-3115 + //llassert(Easy::sActiveHandles.empty()); } //static |