From 71f6b139f8de3ea6bf2b925e095fc0f7864c0274 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 29 May 2020 20:10:04 +0300
Subject: SL-13348 Thread crashing singleton #1

---
 indra/llmessage/llproxy.cpp | 45 ++++++++++++++++++++++++++++-----------------
 indra/llmessage/llproxy.h   |  8 +++++++-
 2 files changed, 35 insertions(+), 18 deletions(-)

(limited to 'indra/llmessage')

diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 950599217f..d11a1487ab 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -40,6 +40,7 @@
 // incoming packet just to do a simple bool test. The getter for this
 // member is also static
 bool LLProxy::sUDPProxyEnabled = false;
+LLProxy* LLProxy::sProxyInstance = NULL;
 
 // Some helpful TCP static functions.
 static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
@@ -60,11 +61,21 @@ LLProxy::LLProxy():
 
 LLProxy::~LLProxy()
 {
-	if (ll_apr_is_initialized())
-	{
-		stopSOCKSProxy();
-		disableHTTPProxy();
-	}
+    if (ll_apr_is_initialized())
+    {
+        // locks mutex
+        stopSOCKSProxy();
+        disableHTTPProxy();
+    }
+    // The primary safety of sProxyInstance is the fact that by the
+    // point SUBSYSTEM_CLEANUP(LLProxy) gets called, nothing should
+    // be capable of using proxy
+    sProxyInstance = NULL;
+}
+
+void LLProxy::initSingleton()
+{
+    sProxyInstance = this;
 }
 
 /**
@@ -424,28 +435,28 @@ void LLProxy::cleanupClass()
 void LLProxy::applyProxySettings(CURL* handle)
 {
 	// Do a faster unlocked check to see if we are supposed to proxy.
-	if (mHTTPProxyEnabled)
+	if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled)
 	{
-		// We think we should proxy, lock the proxy mutex.
-		LLMutexLock lock(&mProxyMutex);
+		// We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex
+		LLMutexLock lock(&sProxyInstance->mProxyMutex);
 		// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
-		if (mHTTPProxyEnabled)
+		if (sProxyInstance->mHTTPProxyEnabled)
 		{
-            LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
-            LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
+			LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
+			LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
 
-			if (mProxyType == LLPROXY_SOCKS)
+			if (sProxyInstance->mProxyType == LLPROXY_SOCKS)
 			{
-                LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
-				if (mAuthMethodSelected == METHOD_PASSWORD)
+				LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
+				if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD)
 				{
-					std::string auth_string = mSocksUsername + ":" + mSocksPassword;
-                    LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
+					std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword;
+					LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
 				}
 			}
 			else
 			{
-                LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
+				LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
 			}
 		}
 	}
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 87891901ad..f2eefb26d0 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -225,6 +225,8 @@ class LLProxy: public LLSingleton<LLProxy>
 	LLSINGLETON(LLProxy);
 	LOG_CLASS(LLProxy);
 
+    /*virtual*/ void initSingleton();
+
 public:
 	// Static check for enabled status for UDP packets. Call from main thread only.
 	static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
@@ -250,7 +252,7 @@ public:
 
 	// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
 	// Safe to call from any thread.
-	void applyProxySettings(CURL* handle);
+	static void applyProxySettings(CURL* handle);
 	// Start a connection to the SOCKS 5 proxy. Call from main thread only.
 	S32 startSOCKSProxy(LLHost host);
 
@@ -343,6 +345,10 @@ private:
 	/*###########################################################################################
 	END OF SHARED MEMBERS
 	###########################################################################################*/
+
+    // A hack to get arround getInstance() and capture_dependency() which are unsafe to use inside threads
+    // set/reset on init/cleanup, strictly for use in applyProxySettings
+    static LLProxy* sProxyInstance;
 };
 
 #endif
-- 
cgit v1.2.3


From 6fddbeb3973c3cd2135ba101afc13329a8c9fe49 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 4 Jun 2020 22:43:55 +0300
Subject: SL-12748 Blocked username displays old name after name change

---
 indra/llmessage/llavatarnamecache.cpp | 17 +++++++++++++++++
 indra/llmessage/llavatarnamecache.h   |  4 ++++
 2 files changed, 21 insertions(+)

(limited to 'indra/llmessage')

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 6a287f0cc5..6ada12962c 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -285,12 +285,27 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
 		return;
 	}
 
+    bool updated_account = true; // assume obsolete value for new arrivals by default
+
+    std::map<LLUUID, LLAvatarName>::iterator it = mCache.find(agent_id);
+    if (it != mCache.end()
+        && (*it).second.getAccountName() == av_name.getAccountName())
+    {
+        updated_account = false;
+    }
+
 	// Add to the cache
 	mCache[agent_id] = av_name;
 
 	// Suppress request from the queue
 	mPendingQueue.erase(agent_id);
 
+	// notify mute list about changes
+    if (updated_account && mAccountNameChangedCallback)
+    {
+        mAccountNameChangedCallback(agent_id, av_name);
+    }
+
 	// Signal everyone waiting on this name
 	signal_map_t::iterator sig_it =	mSignalMap.find(agent_id);
 	if (sig_it != mSignalMap.end())
@@ -303,6 +318,8 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
 		delete signal;
 		signal = NULL;
 	}
+
+
 }
 
 void LLAvatarNameCache::requestNamesViaCapability()
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index ba89d569f3..549d1703fa 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -42,6 +42,7 @@ class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache>
 	~LLAvatarNameCache();
 public:
 	typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
+	typedef boost::function<void (const LLUUID id, const LLAvatarName& av_name)> account_name_changed_callback_t;
 
 	// Import/export the name cache to file.
 	bool importFile(std::istream& istr);
@@ -103,6 +104,8 @@ public:
 
 	void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
 
+    void setAccountNameChangedCallback(const account_name_changed_callback_t& cb) { mAccountNameChangedCallback = cb; }
+
 private:
     // Handle name response off network.
     void processName(const LLUUID& agent_id,
@@ -141,6 +144,7 @@ private:
 private:
 
     use_display_name_signal_t mUseDisplayNamesSignal;
+    account_name_changed_callback_t mAccountNameChangedCallback;
 
     // Cache starts in a paused state until we can determine if the
     // current region supports display names.
-- 
cgit v1.2.3


From fc63aa74247b9a62871cf2ee929457d68bfdf63d Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 9 Oct 2020 21:53:53 +0300
Subject: SL-14078 No point in verifying display name cap each frame

Convoluted due to multiple workarounds. Might be a good idea to spend some time refactoring this, but for now just trottled checks.
---
 indra/llmessage/llavatarnamecache.cpp | 6 ++++++
 indra/llmessage/llavatarnamecache.h   | 2 ++
 2 files changed, 8 insertions(+)

(limited to 'indra/llmessage')

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 7380df041d..756fb940aa 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -549,6 +549,12 @@ void LLAvatarNameCache::idle()
     eraseUnrefreshed();
 }
 
+//static
+bool LLAvatarNameCache::hasWork()
+{
+    return sRequestTimer.hasExpired();
+}
+
 bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
 {
 	bool isPending = false;
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 549d1703fa..04400490c7 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -62,6 +62,8 @@ public:
 	// cache. Called once per frame.
 	void idle();
 
+    static bool hasWork();
+
 	// If name is in cache, returns true and fills in provided LLAvatarName
 	// otherwise returns false.
 	static bool get(const LLUUID& agent_id, LLAvatarName *av_name);
-- 
cgit v1.2.3


From 0a2b748705c6e74eaff814d48b8b110c1364b45f Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Mon, 12 Oct 2020 18:35:43 +0300
Subject: SL-14078 No point in verifying display name cap each frame #2

---
 indra/llmessage/llavatarnamecache.cpp | 6 ------
 indra/llmessage/llavatarnamecache.h   | 2 --
 2 files changed, 8 deletions(-)

(limited to 'indra/llmessage')

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 756fb940aa..7380df041d 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -549,12 +549,6 @@ void LLAvatarNameCache::idle()
     eraseUnrefreshed();
 }
 
-//static
-bool LLAvatarNameCache::hasWork()
-{
-    return sRequestTimer.hasExpired();
-}
-
 bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
 {
 	bool isPending = false;
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 04400490c7..549d1703fa 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -62,8 +62,6 @@ public:
 	// cache. Called once per frame.
 	void idle();
 
-    static bool hasWork();
-
 	// If name is in cache, returns true and fills in provided LLAvatarName
 	// otherwise returns false.
 	static bool get(const LLUUID& agent_id, LLAvatarName *av_name);
-- 
cgit v1.2.3