diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 195e28bc9e..1149e38b06 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -287,6 +287,11 @@ private:
U8 mImageCodec;
LLViewerAssetStats::duration_t mMetricsStartTime;
+
+ // CURL timeout check
+ LLFrameTimer mHttpCallbackTimer;
+ S32 mHttpCallbackTimeoutCount;
+ // CURL timeout check
};
//////////////////////////////////////////////////////////////////////////////
@@ -683,7 +688,11 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mLastPacket(-1),
mTotalPackets(0),
mImageCodec(IMG_CODEC_INVALID),
- mMetricsStartTime(0)
+ // CURL timeout check
+ //mMetricsStartTime(0)
+ mMetricsStartTime(0),
+ mHttpCallbackTimeoutCount(0)
+ // CURL timeout check
{
mCanUseNET = mUrl.empty() ;
@@ -1217,6 +1226,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
headers.push_back("Accept: image/x-j2c");
res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize,
new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
+
+ mHttpCallbackTimer.reset(); // CURL timeout check
}
if (!res)
{
@@ -1377,8 +1388,57 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
else
{
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
- return false;
+ // CURL timeout check: In case CURL does not
+ // fire the callback method, the fetch worker
+ // thread would be stuck in the queue.
+ //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ //return false;
+ const F32 HTTP_CALLBACK_TIMEOUT = 30.f;
+ const S32 MAX_HTTP_CALLBACK_TIMEOUTS = 3;
+ if (mHttpCallbackTimer.getElapsedTimeF32() > HTTP_CALLBACK_TIMEOUT)
+ {
+ mFetcher->removeFromHTTPQueue(mID);
+ mHttpCallbackTimeoutCount++;
+ if (mHttpCallbackTimeoutCount < MAX_HTTP_CALLBACK_TIMEOUTS)
+ {
+ // Maximum retries not reached. Try again via HTTP.
+ llwarns << "HTTP callback timeout for " << mID
+ << " (Attempt " << mHttpCallbackTimeoutCount
+ << "/" << MAX_HTTP_CALLBACK_TIMEOUTS << "). Retrying..." << llendl;
+ mState = SEND_HTTP_REQ;
+ return false;
+ }
+ else
+ {
+ mHttpCallbackTimer.stop();
+
+ // Maximum retries reached. Try via simulator
+ // fetch if possible. Abort if not.
+ if (mCanUseNET)
+ {
+ llwarns << "HTTP callback timeout limit reached for " << mID
+ << ". Retrying via simulator fetch..." << llendl;
+ mState = INIT;
+ mCanUseHTTP = false;
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ return false;
+ }
+ else
+ {
+ llwarns << "HTTP callback timeout limit reached for " << mID
+ << ". No simulator fetch available. Aborting!" << llendl;
+ mState = DONE;
+ return true;
+ }
+ }
+ }
+ else
+ {
+ // Timeout not reached. Continue waiting...
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ return false;
+ }
+ // CURL timeout check
}
}