summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2013-07-30 15:21:31 -0400
committerMonty Brandenberg <monty@lindenlab.com>2013-07-30 15:21:31 -0400
commitf3927c6ca2aad757fe88fdd59b87986ca8b207a8 (patch)
tree198943266fcdc6631bfaa0fdbe8eab5d8791e7d8 /indra/newview
parent46dd3df73370590f61eb9a2cffcd732463a4319b (diff)
SH-4371 Reduce 22mS inter-connection latency.
This really extended into the client-side request throttling. Moved this from llmeshrepository (which doesn't really want to do connection management) into llcorehttp. It's now a class option with configurable rate. This still isn't the right thing to do as it creates coupling between viewer and services. When we get to pipelining, this notion becomes invalid.
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llappcorehttp.cpp31
-rwxr-xr-xindra/newview/llmeshrepository.cpp59
-rwxr-xr-xindra/newview/llmeshrepository.h11
3 files changed, 49 insertions, 52 deletions
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 104debe023..b90b9749f9 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -40,32 +40,33 @@ static const struct
U32 mMin;
U32 mMax;
U32 mDivisor;
+ U32 mRate;
std::string mKey;
const char * mUsage;
} init_data[] = // Default and dynamic values for classes
{
{
- LLAppCoreHttp::AP_TEXTURE, 8, 1, 12, 1,
+ LLAppCoreHttp::AP_TEXTURE, 8, 1, 12, 1, 0,
"TextureFetchConcurrency",
"texture fetch"
},
{
- LLAppCoreHttp::AP_MESH1, 32, 1, 128, 1,
+ LLAppCoreHttp::AP_MESH1, 32, 1, 128, 1, 100,
"MeshMaxConcurrentRequests",
"mesh fetch"
},
{
- LLAppCoreHttp::AP_MESH2, 8, 1, 32, 4,
+ LLAppCoreHttp::AP_MESH2, 8, 1, 32, 4, 100,
"MeshMaxConcurrentRequests",
"mesh2 fetch"
},
{
- LLAppCoreHttp::AP_LARGE_MESH, 2, 1, 8, 1,
+ LLAppCoreHttp::AP_LARGE_MESH, 2, 1, 8, 1, 0,
"",
"large mesh fetch"
},
{
- LLAppCoreHttp::AP_UPLOADS, 2, 1, 8, 1,
+ LLAppCoreHttp::AP_UPLOADS, 2, 1, 8, 1, 0,
"",
"asset upload"
}
@@ -267,10 +268,28 @@ void LLAppCoreHttp::cleanup()
void LLAppCoreHttp::refreshSettings(bool initial)
{
+ LLCore::HttpStatus status;
+
for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
{
const EAppPolicy policy(init_data[i].mPolicy);
+ // Set any desired throttle
+ if (initial && init_data[i].mRate)
+ {
+ // Init-time only, can use the static setters here
+ status = LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_THROTTLE_RATE,
+ mPolicies[policy],
+ init_data[i].mRate,
+ NULL);
+ if (! status)
+ {
+ LL_WARNS("Init") << "Unable to set " << init_data[i].mUsage
+ << " throttle rate. Reason: " << status.toString()
+ << LL_ENDL;
+ }
+ }
+
// Get target connection concurrency value
U32 setting(init_data[i].mDefault);
if (! init_data[i].mKey.empty() && gSavedSettings.controlExists(init_data[i].mKey))
@@ -299,7 +318,7 @@ void LLAppCoreHttp::refreshSettings(bool initial)
setting, NULL);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
- LLCore::HttpStatus status(mRequest->getStatus());
+ status = mRequest->getStatus();
LL_WARNS("Init") << "Unable to set " << init_data[i].mUsage
<< " concurrency. Reason: " << status.toString()
<< LL_ENDL;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d02384f87c..e9b1a10e73 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -229,7 +229,6 @@
LLMeshRepository gMeshRepo;
const S32 MESH_HEADER_SIZE = 4096; // Important: assumption is that headers fit in this space
-const U32 MAX_MESH_REQUESTS_PER_SECOND = 100;
const S32 REQUEST_HIGH_WATER_MIN = 32;
const S32 REQUEST_HIGH_WATER_MAX = 80;
const S32 REQUEST_LOW_WATER_MIN = 16;
@@ -613,7 +612,6 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content,
LLMeshRepoThread::LLMeshRepoThread()
: LLThread("mesh repo"),
mWaiting(false),
- mHttpRetries(0U),
mHttpRequest(NULL),
mHttpOptions(NULL),
mHttpLargeOptions(NULL),
@@ -701,23 +699,9 @@ void LLMeshRepoThread::run()
if (! LLApp::isQuitting())
{
- static U32 count = 0;
- static F32 last_hundred = gFrameTimeSeconds;
-
- if (gFrameTimeSeconds - last_hundred > 1.f)
- { //a second has gone by, clear count
- last_hundred = gFrameTimeSeconds;
- count = 0;
- }
- else
- {
- count += mHttpRetries;
- }
- mHttpRetries = 0U;
-
- // NOTE: throttling intentionally favors LOD requests over header requests
+ // NOTE: order of queue processing intentionally favors LOD requests over header requests
- while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && mHttpRequestSet.size() < sRequestHighWater)
+ while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
if (! mMutex)
{
@@ -728,7 +712,7 @@ void LLMeshRepoThread::run()
mLODReqQ.pop();
LLMeshRepository::sLODProcessing--;
mMutex->unlock();
- if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
+ if (!fetchMeshLOD(req.mMeshParams, req.mLOD))//failed, resubmit
{
mMutex->lock();
mLODReqQ.push(req) ;
@@ -737,7 +721,7 @@ void LLMeshRepoThread::run()
}
}
- while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && mHttpRequestSet.size() < sRequestHighWater)
+ while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
if (! mMutex)
{
@@ -747,7 +731,7 @@ void LLMeshRepoThread::run()
HeaderRequest req = mHeaderReqQ.front();
mHeaderReqQ.pop();
mMutex->unlock();
- if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit
+ if (!fetchMeshHeader(req.mMeshParams))//failed, resubmit
{
mMutex->lock();
mHeaderReqQ.push(req) ;
@@ -762,14 +746,14 @@ void LLMeshRepoThread::run()
// order will lose. Keep to the throttle enforcement and pay
// attention to the highwater level (enforced in each fetchXXX()
// method).
- if (! mSkinRequests.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && mHttpRequestSet.size() < sRequestHighWater)
+ if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
// *FIXME: this really does need a lock as do the following ones
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter)
{
LLUUID mesh_id = *iter;
- if (!fetchMeshSkinInfo(mesh_id, count))
+ if (!fetchMeshSkinInfo(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -777,13 +761,13 @@ void LLMeshRepoThread::run()
mSkinRequests.swap(incomplete);
}
- if (! mDecompositionRequests.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && mHttpRequestSet.size() < sRequestHighWater)
+ if (! mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter)
{
LLUUID mesh_id = *iter;
- if (!fetchMeshDecomposition(mesh_id, count))
+ if (!fetchMeshDecomposition(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -791,13 +775,13 @@ void LLMeshRepoThread::run()
mDecompositionRequests.swap(incomplete);
}
- if (! mPhysicsShapeRequests.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && mHttpRequestSet.size() < sRequestHighWater)
+ if (! mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter)
{
LLUUID mesh_id = *iter;
- if (!fetchMeshPhysicsShape(mesh_id, count))
+ if (!fetchMeshPhysicsShape(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -965,7 +949,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c
}
-bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, U32& count)
+bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
{
if (!mHeaderMutex)
@@ -1023,7 +1007,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, U32& count)
}
//reading from VFS failed for whatever reason, fetch from sim
- if (count >= MAX_MESH_REQUESTS_PER_SECOND || mHttpRequestSet.size() >= sRequestHighWater)
+ if (mHttpRequestSet.size() >= sRequestHighWater)
{
return false;
}
@@ -1060,7 +1044,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, U32& count)
return ret;
}
-bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id, U32& count)
+bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
{
if (!mHeaderMutex)
{
@@ -1118,7 +1102,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id, U32& count)
}
//reading from VFS failed for whatever reason, fetch from sim
- if (count >= MAX_MESH_REQUESTS_PER_SECOND || mHttpRequestSet.size() >= sRequestHighWater)
+ if (mHttpRequestSet.size() >= sRequestHighWater)
{
return false;
}
@@ -1155,7 +1139,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id, U32& count)
return ret;
}
-bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id, U32& count)
+bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
{
if (!mHeaderMutex)
{
@@ -1212,7 +1196,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id, U32& count)
}
//reading from VFS failed for whatever reason, fetch from sim
- if (count >= MAX_MESH_REQUESTS_PER_SECOND || mHttpRequestSet.size() >= sRequestHighWater)
+ if (mHttpRequestSet.size() >= sRequestHighWater)
{
return false;
}
@@ -1282,7 +1266,7 @@ void LLMeshRepoThread::decActiveHeaderRequests()
}
//return false if failed to get header
-bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
+bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
{
{
//look for mesh in asset in vfs
@@ -1331,7 +1315,6 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
++LLMeshRepository::sHTTPRequestCount;
- ++count;
}
}
@@ -1339,7 +1322,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c
}
//return false if failed to get mesh lod.
-bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count)
+bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{
if (!mHeaderMutex)
{
@@ -1413,7 +1396,6 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
++LLMeshRepository::sHTTPRequestCount;
- ++count;
}
}
else
@@ -2374,11 +2356,8 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
{
mProcessed = true;
- // Accumulate retries, we'll use these to offset the HTTP
- // count and maybe hold to a throttle better.
unsigned int retries(0U);
response->getRetries(NULL, &retries);
- gMeshRepo.mThread->mHttpRetries += retries;
LLMeshRepository::sHTTPRetryCount += retries;
LLCore::HttpStatus status(response->getStatus());
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 70079eed23..400ceb4ad7 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -322,7 +322,6 @@ public:
// llcorehttp library interface objects.
LLCore::HttpStatus mHttpStatus;
- unsigned int mHttpRetries;
LLCore::HttpRequest * mHttpRequest;
LLCore::HttpOptions * mHttpOptions;
LLCore::HttpOptions * mHttpLargeOptions;
@@ -345,8 +344,8 @@ public:
void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
void loadMeshLOD(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 fetchMeshHeader(const LLVolumeParams& mesh_params);
+ bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
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);
@@ -363,15 +362,15 @@ public:
//send request for skin info, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)
- bool fetchMeshSkinInfo(const LLUUID& mesh_id, U32& count);
+ bool fetchMeshSkinInfo(const LLUUID& mesh_id);
//send request for decomposition, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)
- bool fetchMeshDecomposition(const LLUUID& mesh_id, U32& count);
+ bool fetchMeshDecomposition(const LLUUID& mesh_id);
//send request for PhysicsShape, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)
- bool fetchMeshPhysicsShape(const LLUUID& mesh_id, U32& count);
+ bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
static void incActiveLODRequests();
static void decActiveLODRequests();