From 71f6b139f8de3ea6bf2b925e095fc0f7864c0274 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev 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 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 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::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(); public: typedef boost::signals2::signal use_display_name_signal_t; + typedef boost::function 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 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 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