From a12d5d7c6d8d816512ec9fc1355b37ce38a89cce Mon Sep 17 00:00:00 2001
From: Monty Brandenberg <monty@lindenlab.com>
Date: Fri, 28 Jun 2013 20:08:29 -0400
Subject: [PATCH] SH-4312  Clumsy configuration coordination between mesh and
 corehttp Taught llappcorehttp to register signals on the settings values that
 chagne behavior.  Have initialization and settings changes sweep through
 settings and change them.  Dynamic changes are tried but have no effect
 (produce a warning message) as dynamic settings still aren't supported but
 the plumbing is now connected.  Just need to change llcorehttp.  Bounced the
 'teleport started' signal around and it ended up back where it started with
 some cleanup. This is making me less angry...

---
 indra/newview/llappcorehttp.cpp    | 210 ++++++++++++++++++-----------
 indra/newview/llappcorehttp.h      |   9 +-
 indra/newview/llmeshrepository.cpp |  30 +----
 3 files changed, 145 insertions(+), 104 deletions(-)

diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 2467c02d4d5..70e349e33d6 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -28,10 +28,52 @@
 
 #include "llappcorehttp.h"
 
+#include "llappviewer.h"
 #include "llviewercontrol.h"
 
 
 const F64 LLAppCoreHttp::MAX_THREAD_WAIT_TIME(10.0);
+static const struct
+{
+	LLAppCoreHttp::EAppPolicy	mPolicy;
+	U32							mDefault;
+	U32							mMin;
+	U32							mMax;
+	U32							mDivisor;
+	std::string					mKey;
+	const char *				mUsage;
+} init_data[] =					//  Default and dynamic values for classes
+{
+	{
+		LLAppCoreHttp::AP_TEXTURE,			8,		1,		12,		1,
+		"TextureFetchConcurrency",
+		"texture fetch"
+	},
+	{
+		LLAppCoreHttp::AP_MESH1,			32,		1,		128,	1,
+		"MeshMaxConcurrentRequests",
+		"mesh fetch"
+	},
+	{
+		LLAppCoreHttp::AP_MESH2,			8,		1,		32,		4,
+		"MeshMaxConcurrentRequests",
+		"mesh2 fetch"
+	},
+	{
+		LLAppCoreHttp::AP_LARGE_MESH,		2,		1,		8,		1,
+		"",
+		"large mesh fetch"
+	},
+	{
+		LLAppCoreHttp::AP_UPLOADS,			2,		1,		8,		1,
+		"",
+		"asset upload"
+	}
+};
+
+static void teleport_started();
+static void setting_changed();
+
 
 LLAppCoreHttp::LLAppCoreHttp()
 	: mRequest(NULL),
@@ -42,6 +84,7 @@ LLAppCoreHttp::LLAppCoreHttp()
 	for (int i(0); i < LL_ARRAY_SIZE(mPolicies); ++i)
 	{
 		mPolicies[i] = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+		mSettings[i] = 0U;
 	}
 }
 
@@ -55,45 +98,6 @@ LLAppCoreHttp::~LLAppCoreHttp()
 
 void LLAppCoreHttp::init()
 {
-	static const struct
-	{
-		EAppPolicy		mPolicy;
-		U32				mDefault;
-		U32				mMin;
-		U32				mMax;
-		U32				mDivisor;
-		std::string		mKey;
-		const char *	mUsage;
-	} init_data[] =					//  Default and dynamic values for classes
-		  {
-			  {
-				  AP_TEXTURE,			8,		1,		12,		1,
-				  "TextureFetchConcurrency",
-				  "texture fetch"
-			  },
-			  {
-				  // *FIXME:  Should become 32, 1, 32, 1 before release
-				  AP_MESH1,				8,		1,		32,		4,
-				  "MeshMaxConcurrentRequests",
-				  "mesh fetch"
-			  },
-			  {
-				  AP_MESH2,				8,		1,		32,		4,
-				  "MeshMaxConcurrentRequests",
-				  "mesh2 fetch"
-			  },
-			  {
-				  AP_LARGE_MESH,		2,		1,		8,		1,
-				  "",
-				  "large mesh fetch"
-			  },
-			  {
-				  AP_UPLOADS,			2,		1,		8,		1,
-				  "",
-				  "asset upload"
-			  }
-		  };
-		
 	LLCore::HttpStatus status = LLCore::HttpRequest::createService();
 	if (! status)
 	{
@@ -110,14 +114,12 @@ void LLAppCoreHttp::init()
 						<< LL_ENDL;
 	}
 
-	// Establish HTTP Proxy.  "LLProxy" is a special string which directs
-	// the code to use LLProxy::applyProxySettings() to establish any
-	// HTTP or SOCKS proxy for http operations.
+	// Establish HTTP Proxy, if desired.
 	status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_LLPROXY, 1);
 	if (! status)
 	{
-		LL_ERRS("Init") << "Failed to set HTTP proxy for HTTP services.  Reason:  " << status.toString()
-						<< LL_ENDL;
+		LL_WARNS("Init") << "Failed to set HTTP proxy for HTTP services.  Reason:  " << status.toString()
+						 << LL_ENDL;
 	}
 
 	// Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):
@@ -137,7 +139,6 @@ void LLAppCoreHttp::init()
 	mPolicies[AP_DEFAULT] = LLCore::HttpRequest::DEFAULT_POLICY_ID;
 
 	// Setup additional policies based on table and some special rules
-	// *TODO:  Make these configurations dynamic later
 	for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
 	{
 		const EAppPolicy policy(init_data[i].mPolicy);
@@ -162,40 +163,10 @@ void LLAppCoreHttp::init()
 				continue;
 			}
 		}
-
-		// Get target connection concurrency value
-		U32 setting(init_data[i].mDefault);
-		if (! init_data[i].mKey.empty() && gSavedSettings.controlExists(init_data[i].mKey))
-		{
-			U32 new_setting(gSavedSettings.getU32(init_data[i].mKey));
-			if (new_setting)
-			{
-				// Treat zero settings as an ask for default
-				setting = new_setting / init_data[i].mDivisor;
-				setting = llclamp(setting, init_data[i].mMin, init_data[i].mMax);
-			}
-		}
-
-		// Set it and report
-		// *TODO:  These are intended to be per-host limits when we can
-		// support that in llcorehttp/libcurl.
-		LLCore::HttpStatus status;
-		status = LLCore::HttpRequest::setPolicyClassOption(mPolicies[policy],
-														   LLCore::HttpRequest::CP_CONNECTION_LIMIT,
-														   setting);
-		if (! status)
-		{
-			LL_WARNS("Init") << "Unable to set " << init_data[i].mUsage
-							 << " concurrency.  Reason:  " << status.toString()
-							 << LL_ENDL;
-		}
-		else if (setting != init_data[i].mDefault)
-		{
-			LL_INFOS("Init") << "Application settings overriding default " << init_data[i].mUsage
-							 << " concurrency.  New value:  " << setting
-							 << LL_ENDL;
-		}
 	}
+
+	// Apply initial settings
+	refreshSettings(true);
 	
 	// Kick the thread
 	status = LLCore::HttpRequest::startThread();
@@ -206,6 +177,30 @@ void LLAppCoreHttp::init()
 	}
 
 	mRequest = new LLCore::HttpRequest;
+
+	// Register signals for settings and state changes
+	for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
+	{
+		if (! init_data[i].mKey.empty() && gSavedSettings.controlExists(init_data[i].mKey))
+		{
+			LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(init_data[i].mKey);
+			if (cntrl_ptr.isNull())
+			{
+				LL_WARNS("Init") << "Unable to set signal on global setting '" << init_data[i].mKey
+								 << "'" << LL_ENDL;
+			}
+			else
+			{
+				mSettingsSignal[i] = cntrl_ptr->getCommitSignal()->connect(boost::bind(&setting_changed));
+			}
+		}
+	}
+}
+
+
+void setting_changed()
+{
+	LLAppViewer::instance()->getAppCoreHttp().refreshSettings(false);
 }
 
 
@@ -248,6 +243,11 @@ void LLAppCoreHttp::cleanup()
 		}
 	}
 
+	for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
+	{
+		mSettingsSignal[i].disconnect();
+	}
+	
 	delete mRequest;
 	mRequest = NULL;
 
@@ -260,6 +260,60 @@ void LLAppCoreHttp::cleanup()
 	}
 }
 
+void LLAppCoreHttp::refreshSettings(bool initial)
+{
+	for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
+	{
+		const EAppPolicy policy(init_data[i].mPolicy);
+
+		// Get target connection concurrency value
+		U32 setting(init_data[i].mDefault);
+		if (! init_data[i].mKey.empty() && gSavedSettings.controlExists(init_data[i].mKey))
+		{
+			U32 new_setting(gSavedSettings.getU32(init_data[i].mKey));
+			if (new_setting)
+			{
+				// Treat zero settings as an ask for default
+				setting = new_setting / init_data[i].mDivisor;
+				setting = llclamp(setting, init_data[i].mMin, init_data[i].mMax);
+			}
+		}
+
+		if (! initial && setting == mSettings[policy])
+		{
+			// Unchanged, try next setting
+			continue;
+		}
+		
+		// Set it and report
+		// *TODO:  These are intended to be per-host limits when we can
+		// support that in llcorehttp/libcurl.
+		LLCore::HttpStatus status;
+		status = LLCore::HttpRequest::setPolicyClassOption(mPolicies[policy],
+														   LLCore::HttpRequest::CP_CONNECTION_LIMIT,
+														   setting);
+		if (! status)
+		{
+			LL_WARNS("Init") << "Unable to set " << init_data[i].mUsage
+							 << " concurrency.  Reason:  " << status.toString()
+							 << LL_ENDL;
+		}
+		else
+		{
+			LL_DEBUGS("Init") << "Changed " << init_data[i].mUsage
+							  << " concurrency.  New value:  " << setting
+							  << LL_ENDL;
+			mSettings[policy] = setting;
+			if (initial && setting != init_data[i].mDefault)
+			{
+				LL_INFOS("Init") << "Application settings overriding default " << init_data[i].mUsage
+								 << " concurrency.  New value:  " << setting
+								 << LL_ENDL;
+			}
+		}
+	}
+}
+
 
 void LLAppCoreHttp::onCompleted(LLCore::HttpHandle, LLCore::HttpResponse *)
 {
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index 4a14c35966e..6dc3bb21302 100755
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -85,16 +85,21 @@ class LLAppCoreHttp : public LLCore::HttpHandler
 		{
 			return mPolicies[policy];
 		}
+
+	// Apply initial or new settings from the environment.
+	void refreshSettings(bool initial);
 	
 private:
 	static const F64			MAX_THREAD_WAIT_TIME;
 	
 private:
-	LLCore::HttpRequest *		mRequest;
+	LLCore::HttpRequest *		mRequest;						// Request queue to issue shutdowns
 	LLCore::HttpHandle			mStopHandle;
 	F64							mStopRequested;
 	bool						mStopped;
-	policy_t					mPolicies[AP_COUNT];
+	policy_t					mPolicies[AP_COUNT];			// Policy class id for each connection set
+	U32							mSettings[AP_COUNT];
+	boost::signals2::connection mSettingsSignal[AP_COUNT];		// Signals to global settings that affect us
 };
 
 
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index aa10e64af8b..3af9ce7342a 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -259,10 +259,9 @@ const char * const LOG_MESH = "Mesh";
 
 // Static data and functions to measure mesh load
 // time metrics for a new region scene.
-static bool metrics_inited(false);
-static boost::signals2::connection metrics_teleport_connection;
 static unsigned int metrics_teleport_start_count(0);
-static void metrics_teleport_started();
+boost::signals2::connection metrics_teleport_started_signal;
+static void teleport_started();
 static bool is_retryable(LLCore::HttpStatus status);
 
 //get the number of bytes resident in memory for given volume
@@ -2667,29 +2666,18 @@ void LLMeshRepository::init()
 		apr_sleep(100);
 	}
 
-	
+	metrics_teleport_started_signal = LLViewerMessage::getInstance()->setTeleportStartedCallback(teleport_started);
 	
 	mThread = new LLMeshRepoThread();
 	mThread->start();
 
-	if (! metrics_inited)
-	{
-		// Get teleport started signals to restart timings.
-		metrics_teleport_connection = LLViewerMessage::getInstance()->
-			setTeleportStartedCallback(metrics_teleport_started);
-		metrics_inited = true;
-	}
 }
 
 void LLMeshRepository::shutdown()
 {
 	llinfos << "Shutting down mesh repository." << llendl;
 
-	if (metrics_inited)
-	{
-		metrics_teleport_connection.disconnect();
-		metrics_inited = false;
-	}
+	metrics_teleport_started_signal.disconnect();
 
 	for (U32 i = 0; i < mUploads.size(); ++i)
 	{
@@ -4109,6 +4097,7 @@ bool LLMeshRepository::meshRezEnabled()
 // static
 void LLMeshRepository::metricsStart()
 {
+	++metrics_teleport_start_count;
 	sQuiescentTimer.start(0);
 }
 
@@ -4127,7 +4116,6 @@ void LLMeshRepository::metricsProgress(unsigned int this_count)
 
 	if (first_start)
 	{
-		++metrics_teleport_start_count;
 		metricsStart();
 		first_start = false;
 	}
@@ -4157,19 +4145,13 @@ void LLMeshRepository::metricsUpdate()
 	}
 }
 
-// Will use a request to start a teleport as a signal to
-// restart a timing sequence.  We don't get one of these
-// for login so initial start is done above.
-//
 // Threading:  main thread only
 // static
-void metrics_teleport_started()
+void teleport_started()
 {
 	LLMeshRepository::metricsStart();
-	++metrics_teleport_start_count;
 }
 
-
 // This comes from an edit in viewer-cat.  Unify this once that's
 // available everywhere.
 bool is_retryable(LLCore::HttpStatus status)
-- 
GitLab