From 5b1984ed0c448c6861221873e7c70f46545e1136 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Tue, 7 May 2013 19:36:10 +0200 Subject: [PATCH] WIP: Added AIPerService::Approvement --- indra/llmessage/aicurlperservice.cpp | 13 ++++++++++++- indra/llmessage/aicurlperservice.h | 14 +++++++++++++- indra/llmessage/aicurlthread.cpp | 15 +++++++++++++++ indra/newview/app_settings/settings.xml | 7 +++++-- indra/newview/llinventorymodelbackgroundfetch.cpp | 8 ++++++++ indra/newview/lltexturefetch.cpp | 5 +++++ 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/indra/llmessage/aicurlperservice.cpp b/indra/llmessage/aicurlperservice.cpp index 44b650596..8f8573ea6 100644 --- a/indra/llmessage/aicurlperservice.cpp +++ b/indra/llmessage/aicurlperservice.cpp @@ -71,7 +71,7 @@ void intrusive_ptr_release(RefCountedThreadSafePerService* per_service) using namespace AICurlPrivate; AIPerService::AIPerService(void) : - mQueuedCommands(0), mAdded(0), mQueueEmpty(false), + mApprovedRequests(0), mQueuedCommands(0), mAdded(0), mQueueEmpty(false), mQueueFull(false), mRequestStarvation(false), mHTTPBandwidth(25), // 25 = 1000 ms / 40 ms. mConcurrectConnections(CurlConcurrentConnectionsPerService), mMaxPipelinedRequests(CurlConcurrentConnectionsPerService) @@ -355,3 +355,14 @@ void AIPerService::adjust_concurrent_connections(int increment) } } +void AIPerService::Approvement::honored(void) +{ + if (!mHonored) + { + mHonored = true; + AICurlPrivate::PerService_wat per_service_w(*mPerServicePtr); + llassert(per_service_w->mApprovedRequests > 0); + per_service_w->mApprovedRequests--; + } +} + diff --git a/indra/llmessage/aicurlperservice.h b/indra/llmessage/aicurlperservice.h index 3d7e7fe6d..eab41ad80 100644 --- a/indra/llmessage/aicurlperservice.h +++ b/indra/llmessage/aicurlperservice.h @@ -114,6 +114,7 @@ class AIPerService { private: typedef std::deque queued_request_type; + int mApprovedRequests; // The number of approved requests by wantsMoreHTTPRequestsFor that were not added to the command queue yet. int mQueuedCommands; // Number of add commands (minus remove commands) with this host in the command queue. int mAdded; // Number of active easy handles with this host. queued_request_type mQueuedRequests; // Waiting (throttled) requests. @@ -188,7 +189,7 @@ class AIPerService { // Add queued easy handle (if any) to the multi handle. The request is removed from the queue, // followed by either a call to added_to_multi_handle() or to queue() to add it back. - S32 pipelined_requests(void) const { return mQueuedCommands + mQueuedRequests.size() + mAdded; } + S32 pipelined_requests(void) const { return mApprovedRequests + mQueuedCommands + mQueuedRequests.size() + mAdded; } AIAverage& bandwidth(void) { return mHTTPBandwidth; } AIAverage const& bandwidth(void) const { return mHTTPBandwidth; } @@ -212,6 +213,17 @@ class AIPerService { // Return true if too much bandwidth is being used. static bool checkBandwidthUsage(AIPerServicePtr const& per_service, U64 sTime_40ms); + // A helper class to decrement mApprovedRequests after requests approved by wantsMoreHTTPRequestsFor were handled. + class Approvement { + private: + AIPerServicePtr mPerServicePtr; + bool mHonored; + public: + Approvement(AIPerServicePtr const& per_service) : mPerServicePtr(per_service), mHonored(false) { } + ~Approvement() { honored(); } + void honored(void); + }; + private: // Disallow copying. AIPerService(AIPerService const&); diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index 6f0da9608..eebd62db1 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -2650,6 +2650,7 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service) { PerService_wat per_service_w(*per_service); S32 const pipelined_requests_per_service = per_service_w->pipelined_requests(); + llassert(pipelined_requests_per_service >= 0 && pipelined_requests_per_service <= 16); reject = pipelined_requests_per_service >= per_service_w->mMaxPipelinedRequests; equal = pipelined_requests_per_service == per_service_w->mMaxPipelinedRequests; increment_threshold = per_service_w->mRequestStarvation; @@ -2672,6 +2673,13 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service) reject = !equal; } } + if (!reject) + { + // Before releasing the lock on per_service, stop other threads from getting a + // too small value from pipelined_requests() and approving too many requests. + per_service_w->mApprovedRequests++; + llassert(per_service_w->mApprovedRequests <= 16); + } } if (reject) { @@ -2683,6 +2691,7 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service) if (checkBandwidthUsage(per_service, sTime_40ms)) { // Too much bandwidth is being used, either in total or for this service. + PerService_wat(*per_service)->mApprovedRequests--; // Not approved after all. return false; } @@ -2714,6 +2723,10 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service) reject = !equal; } } + if (reject) + { + PerService_wat(*per_service)->mApprovedRequests--; // Not approved after all. + } return !reject; } @@ -2773,6 +2786,8 @@ bool AIPerService::checkBandwidthUsage(AIPerServicePtr const& per_service, U64 s } // Throttle this service if it uses too much bandwidth. + // Warning: this requires max_bandwidth * 1024 to fit in a size_t. + // On 32 bit that means that HTTPThrottleBandwidth must be less than 33554 kbps. return (service_bandwidth > (max_bandwidth * throttle_fraction_w->fraction / 1024)); } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 61f8f21bc..e40ed23d7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -175,7 +175,10 @@ HTTPThrottleBandwidth Comment - The bandwidth (in kbit/s) to strive for + The bandwidth (in kbit/s) to strive for. Smaller values might reduce network + congestion (sim ping time, aka avatar responsiveness). Higher values might download + textures and the inventory faster, although in some cases a too high value might + actually slow that down due to serverside throttling. If unsure, choose 2000. Persist 1 Type @@ -4468,7 +4471,7 @@ This should be as low as possible, but too low may break functionality Type U32 Value - 16 + 8 CurlTimeoutDNSLookup diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index ebeaba505..0f1d93c5c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -604,6 +604,10 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { return; // Wait. } + // If AIPerService::wantsMoreHTTPRequestsFor returns true, then it approved ONE request. + // The code below might fire off zero, one or even more than one requests however! + // This object keeps track of that. + AIPerService::Approvement approvement(mPerServicePtr); U32 item_count=0; U32 folder_count=0; @@ -698,6 +702,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); LLHTTPClient::post_nb(url, folder_request_body, fetcher); + approvement.honored(); } if (folder_request_body_lib["folders"].size()) { @@ -705,6 +710,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); LLHTTPClient::post_nb(url_lib, folder_request_body_lib, fetcher); + approvement.honored(); } } if (item_count) @@ -723,6 +729,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() body["items"] = item_request_body; LLHTTPClient::post_nb(url, body, new LLInventoryModelFetchItemResponder(body)); + approvement.honored(); } } @@ -739,6 +746,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() body["items"] = item_request_body_lib; LLHTTPClient::post_nb(url, body, new LLInventoryModelFetchItemResponder(body)); + approvement.honored(); } } } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 3206af56f..56a6267b2 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1276,6 +1276,9 @@ bool LLTextureFetchWorker::doWork(S32 param) { return false ; //wait. } + // If AIPerService::wantsMoreHTTPRequestsFor returns true then it approved ONE request. + // This object keeps track of whether or not that is honored. + AIPerService::Approvement approvement(mPerServicePtr); mFetcher->removeFromNetworkQueue(this, false); @@ -1322,6 +1325,8 @@ bool LLTextureFetchWorker::doWork(S32 param) LLHTTPClient::request(mUrl, LLHTTPClient::HTTP_GET, NULL, new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, mRequestedOffset, true), headers/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, no_does_authentication, allow_compressed_reply, NULL, 0, NULL, false); + // Now the request was added to the command queue. + approvement.honored(); res = true; } if (!res)