From 779b5627c5e9c76a06938cd4e73a5b8f0440cabc Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 3 Jul 2019 20:06:47 +0300 Subject: DRTVWR-493 LLAvatarNameCache to singletone --- indra/llmessage/llavatarnamecache.cpp | 281 ++++++++++++++-------------------- indra/llmessage/llavatarnamecache.h | 98 ++++++++++-- 2 files changed, 199 insertions(+), 180 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index ba1a2a035e..6a287f0cc5 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -49,101 +49,22 @@ #include #include -namespace LLAvatarNameCache -{ - use_display_name_signal_t mUseDisplayNamesSignal; - - // Cache starts in a paused state until we can determine if the - // current region supports display names. - bool sRunning = false; - - // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false. - // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer). - bool sUsePeopleAPI = true; - - // Base lookup URL for name service. - // On simulator, loaded from indra.xml - // On viewer, usually a simulator capability (at People API team's request) - // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/" - std::string sNameLookupURL; - - // Accumulated agent IDs for next query against service - typedef std::set ask_queue_t; - ask_queue_t sAskQueue; - - // Agent IDs that have been requested, but with no reply. - // Maps agent ID to frame time request was made. - typedef std::map pending_queue_t; - pending_queue_t sPendingQueue; - - // Callbacks to fire when we received a name. - // May have multiple callbacks for a single ID, which are - // represented as multiple slots bound to the signal. - // Avoid copying signals via pointers. - typedef std::map signal_map_t; - signal_map_t sSignalMap; - - // The cache at last, i.e. avatar names we know about. - typedef std::map cache_t; - cache_t sCache; - - // Send bulk lookup requests a few times a second at most. - // Only need per-frame timing resolution. - LLFrameTimer sRequestTimer; - - // Maximum time an unrefreshed cache entry is allowed. - const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; - - // Time when unrefreshed cached names were checked last. - static F64 sLastExpireCheck; - - // Time-to-live for a temp cache entry. - const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; - - LLCore::HttpRequest::ptr_t sHttpRequest; - LLCore::HttpHeaders::ptr_t sHttpHeaders; - LLCore::HttpOptions::ptr_t sHttpOptions; - LLCore::HttpRequest::policy_t sHttpPolicy; - LLCore::HttpRequest::priority_t sHttpPriority; - - //----------------------------------------------------------------------- - // Internal methods - //----------------------------------------------------------------------- - - // Handle name response off network. - void processName(const LLUUID& agent_id, - const LLAvatarName& av_name); - - void requestNamesViaCapability(); - - // Legacy name system callbacks - void legacyNameCallback(const LLUUID& agent_id, - const std::string& full_name, - bool is_group); - void legacyNameFetch(const LLUUID& agent_id, - const std::string& full_name, - bool is_group); - - void requestNamesViaLegacy(); - - // Do a single callback to a given slot - void fireSignal(const LLUUID& agent_id, - const callback_slot_t& slot, - const LLAvatarName& av_name); - - // Is a request in-flight over the network? - bool isRequestPending(const LLUUID& agent_id); - // Erase expired names from cache - void eraseUnrefreshed(); +// Time-to-live for a temp cache entry. +const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; +// Maximum time an unrefreshed cache entry is allowed. +const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; - bool expirationFromCacheControl(const LLSD& headers, F64 *expires); +// Send bulk lookup requests a few times a second at most. +// Only need per-frame timing resolution. +static LLFrameTimer sRequestTimer; - // This is a coroutine. - void requestAvatarNameCache_(std::string url, std::vector agentIds); - - void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult); -} +// static to avoid unnessesary dependencies +LLCore::HttpRequest::ptr_t sHttpRequest; +LLCore::HttpHeaders::ptr_t sHttpHeaders; +LLCore::HttpOptions::ptr_t sHttpOptions; +LLCore::HttpRequest::policy_t sHttpPolicy; +LLCore::HttpRequest::priority_t sHttpPriority; /* Sample response: @@ -187,6 +108,30 @@ namespace LLAvatarNameCache // Coroutine for sending and processing avatar name cache requests. // Do not call directly. See documentation in lleventcoro.h and llcoro.h for // further explanation. + +LLAvatarNameCache::LLAvatarNameCache() +{ + // Will be set to running later + // For now fail immediate lookups and query async ones. + mRunning = false; + + mUsePeopleAPI = true; + + sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); + sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()); + sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); + sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; + sHttpPriority = 0; +} + +LLAvatarNameCache::~LLAvatarNameCache() +{ + sHttpRequest.reset(); + sHttpHeaders.reset(); + sHttpOptions.reset(); + mCache.clear(); +} + void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector agentIds) { LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName() @@ -205,7 +150,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vectorhandleAgentError(agent_id); } return; } - LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults); + LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); } catch (...) @@ -300,15 +245,15 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h } } LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result " - << LLAvatarNameCache::sCache.size() << " cached names" + << LLAvatarNameCache::mCache.size() << " cached names" << LL_ENDL; } // Provide some fallback for agents that return errors void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) { - std::map::iterator existing = sCache.find(agent_id); - if (existing == sCache.end()) + std::map::iterator existing = mCache.find(agent_id); + if (existing == mCache.end()) { // there is no existing cache entry, so make a temporary name from legacy LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent " @@ -322,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) // been returned by the get method, there is no need to signal anyone // Clear this agent from the pending list - LLAvatarNameCache::sPendingQueue.erase(agent_id); + LLAvatarNameCache::mPendingQueue.erase(agent_id); LLAvatarName& av_name = existing->second; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL; @@ -341,19 +286,19 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& } // Add to the cache - sCache[agent_id] = av_name; + mCache[agent_id] = av_name; // Suppress request from the queue - sPendingQueue.erase(agent_id); + mPendingQueue.erase(agent_id); // Signal everyone waiting on this name - signal_map_t::iterator sig_it = sSignalMap.find(agent_id); - if (sig_it != sSignalMap.end()) + signal_map_t::iterator sig_it = mSignalMap.find(agent_id); + if (sig_it != mSignalMap.end()) { callback_signal_t* signal = sig_it->second; (*signal)(agent_id, av_name); - sSignalMap.erase(agent_id); + mSignalMap.erase(agent_id); delete signal; signal = NULL; @@ -379,16 +324,16 @@ void LLAvatarNameCache::requestNamesViaCapability() U32 ids = 0; ask_queue_t::const_iterator it; - while(!sAskQueue.empty()) + while(!mAskQueue.empty()) { - it = sAskQueue.begin(); + it = mAskQueue.begin(); LLUUID agent_id = *it; - sAskQueue.erase(it); + mAskQueue.erase(it); if (url.empty()) { // ...starting new request - url += sNameLookupURL; + url += mNameLookupURL; url += "?ids="; ids = 1; } @@ -402,7 +347,7 @@ void LLAvatarNameCache::requestNamesViaCapability() agent_ids.push_back(agent_id); // mark request as pending - sPendingQueue[agent_id] = now; + mPendingQueue[agent_id] = now; if (url.size() > NAME_URL_SEND_THRESHOLD) { @@ -432,7 +377,7 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, // Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy // protocol, we do not get an expiration date for each name and there's no reason to ask the // data again and again so we set the expiration time to the largest value admissible. - std::map::iterator av_record = sCache.find(agent_id); + std::map::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id); LLAvatarName& av_name = av_record->second; av_name.setExpires(MAX_UNREFRESHED_TIME); } @@ -451,7 +396,7 @@ void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id, av_name.fromString(full_name); // Add to cache: we're still using the new cache even if we're using the old (legacy) protocol. - processName(agent_id, av_name); + LLAvatarNameCache::getInstance()->processName(agent_id, av_name); } void LLAvatarNameCache::requestNamesViaLegacy() @@ -460,15 +405,15 @@ void LLAvatarNameCache::requestNamesViaLegacy() F64 now = LLFrameTimer::getTotalSeconds(); std::string full_name; ask_queue_t::const_iterator it; - for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests) + for (S32 requests = 0; !mAskQueue.empty() && requests < MAX_REQUESTS; ++requests) { - it = sAskQueue.begin(); + it = mAskQueue.begin(); LLUUID agent_id = *it; - sAskQueue.erase(it); + mAskQueue.erase(it); // Mark as pending first, just in case the callback is immediately // invoked below. This should never happen in practice. - sPendingQueue[agent_id] = now; + mPendingQueue[agent_id] = now; LL_DEBUGS("AvNameCache") << "agent " << agent_id << LL_ENDL; @@ -477,26 +422,6 @@ void LLAvatarNameCache::requestNamesViaLegacy() } } -void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI) -{ - sRunning = running; - sUsePeopleAPI = usePeopleAPI; - - sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); - sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()); - sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); - sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; - sHttpPriority = 0; -} - -void LLAvatarNameCache::cleanupClass() -{ - sHttpRequest.reset(); - sHttpHeaders.reset(); - sHttpOptions.reset(); - sCache.clear(); -} - bool LLAvatarNameCache::importFile(std::istream& istr) { LLSD data; @@ -517,9 +442,9 @@ bool LLAvatarNameCache::importFile(std::istream& istr) { agent_id.set(it->first); av_name.fromLLSD( it->second ); - sCache[agent_id] = av_name; + mCache[agent_id] = av_name; } - LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << sCache.size() << LL_ENDL; + LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << mCache.size() << LL_ENDL; // Some entries may have expired since the cache was stored, // but they will be flushed in the first call to eraseUnrefreshed // from LLAvatarNameResponder::idle @@ -531,9 +456,9 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr) { LLSD agents; F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME; - LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << sCache.size() << LL_ENDL; - cache_t::const_iterator it = sCache.begin(); - for ( ; it != sCache.end(); ++it) + LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << mCache.size() << LL_ENDL; + cache_t::const_iterator it = mCache.begin(); + for ( ; it != mCache.end(); ++it) { const LLUUID& agent_id = it->first; const LLAvatarName& av_name = it->second; @@ -552,23 +477,28 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr) void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url) { - sNameLookupURL = name_lookup_url; + mNameLookupURL = name_lookup_url; } bool LLAvatarNameCache::hasNameLookupURL() { - return !sNameLookupURL.empty(); + return !mNameLookupURL.empty(); +} + +void LLAvatarNameCache::setUsePeopleAPI(bool use_api) +{ + mUsePeopleAPI = use_api; } bool LLAvatarNameCache::usePeopleAPI() { - return hasNameLookupURL() && sUsePeopleAPI; + return hasNameLookupURL() && mUsePeopleAPI; } void LLAvatarNameCache::idle() { // By convention, start running at first idle() call - sRunning = true; + mRunning = true; // *TODO: Possibly re-enabled this based on People API load measurements // 100 ms is the threshold for "user speed" operations, so we can @@ -579,7 +509,7 @@ void LLAvatarNameCache::idle() return; } - if (!sAskQueue.empty()) + if (!mAskQueue.empty()) { if (usePeopleAPI()) { @@ -592,7 +522,7 @@ void LLAvatarNameCache::idle() } } - if (sAskQueue.empty()) + if (mAskQueue.empty()) { // cleared the list, reset the request timer. sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS); @@ -607,8 +537,8 @@ bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id) bool isPending = false; const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; - pending_queue_t::const_iterator it = sPendingQueue.find(agent_id); - if (it != sPendingQueue.end()) + pending_queue_t::const_iterator it = mPendingQueue.find(agent_id); + if (it != mPendingQueue.end()) { // in the list of requests in flight, retry if too old F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; @@ -622,11 +552,11 @@ void LLAvatarNameCache::eraseUnrefreshed() F64 now = LLFrameTimer::getTotalSeconds(); F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME; - if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed) + if (!mLastExpireCheck || mLastExpireCheck < max_unrefreshed) { - sLastExpireCheck = now; + mLastExpireCheck = now; S32 expired = 0; - for (cache_t::iterator it = sCache.begin(); it != sCache.end();) + for (cache_t::iterator it = mCache.begin(); it != mCache.end();) { const LLAvatarName& av_name = it->second; if (av_name.mExpires < max_unrefreshed) @@ -635,7 +565,7 @@ void LLAvatarNameCache::eraseUnrefreshed() << " user '" << av_name.getAccountName() << "' " << "expired " << now - av_name.mExpires << " secs ago" << LL_ENDL; - sCache.erase(it++); + mCache.erase(it++); expired++; } else @@ -644,19 +574,24 @@ void LLAvatarNameCache::eraseUnrefreshed() } } LL_INFOS("AvNameCache") << "LLAvatarNameCache expired " << expired << " cached avatar names, " - << sCache.size() << " remaining" << LL_ENDL; + << mCache.size() << " remaining" << LL_ENDL; } } +//static, wrapper +bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +{ + return LLAvatarNameCache::getInstance()->getName(agent_id, av_name); +} // fills in av_name if it has it in the cache, even if expired (can check expiry time) // returns bool specifying if av_name was filled, false otherwise -bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name) { - if (sRunning) + if (mRunning) { // ...only do immediate lookups when cache is running - std::map::iterator it = sCache.find(agent_id); - if (it != sCache.end()) + std::map::iterator it = mCache.find(agent_id); + if (it != mCache.end()) { *av_name = it->second; @@ -667,7 +602,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) { LL_DEBUGS("AvNameCache") << "LLAvatarNameCache refresh agent " << agent_id << LL_ENDL; - sAskQueue.insert(agent_id); + mAskQueue.insert(agent_id); } } @@ -678,7 +613,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) if (!isRequestPending(agent_id)) { LL_DEBUGS("AvNameCache") << "LLAvatarNameCache queue request for agent " << agent_id << LL_ENDL; - sAskQueue.insert(agent_id); + mAskQueue.insert(agent_id); } return false; @@ -693,15 +628,21 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id, signal(agent_id, av_name); } +// static, wrapper LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) +{ + return LLAvatarNameCache::getInstance()->getNameCallback(agent_id, slot); +} + +LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(const LLUUID& agent_id, callback_slot_t slot) { callback_connection_t connection; - if (sRunning) + if (mRunning) { // ...only do immediate lookups when cache is running - std::map::iterator it = sCache.find(agent_id); - if (it != sCache.end()) + std::map::iterator it = mCache.find(agent_id); + if (it != mCache.end()) { const LLAvatarName& av_name = it->second; @@ -717,17 +658,17 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag // schedule a request if (!isRequestPending(agent_id)) { - sAskQueue.insert(agent_id); + mAskQueue.insert(agent_id); } // always store additional callback, even if request is pending - signal_map_t::iterator sig_it = sSignalMap.find(agent_id); - if (sig_it == sSignalMap.end()) + signal_map_t::iterator sig_it = mSignalMap.find(agent_id); + if (sig_it == mSignalMap.end()) { // ...new callback for this id callback_signal_t* signal = new callback_signal_t(); connection = signal->connect(slot); - sSignalMap[agent_id] = signal; + mSignalMap[agent_id] = signal; } else { @@ -760,20 +701,20 @@ void LLAvatarNameCache::setUseUsernames(bool use) void LLAvatarNameCache::erase(const LLUUID& agent_id) { - sCache.erase(agent_id); + mCache.erase(agent_id); } void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name) { // *TODO: update timestamp if zero? - sCache[agent_id] = av_name; + mCache[agent_id] = av_name; } LLUUID LLAvatarNameCache::findIdByName(const std::string& name) { std::map::iterator it; - std::map::iterator end = sCache.end(); - for (it = sCache.begin(); it != end; ++it) + std::map::iterator end = mCache.end(); + for (it = mCache.begin(); it != end; ++it) { if (it->second.getUserName() == name) { diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 63e067c939..ba89d569f3 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -29,21 +29,20 @@ #define LLAVATARNAMECACHE_H #include "llavatarname.h" // for convenience +#include "llsingleton.h" #include +#include class LLSD; class LLUUID; -namespace LLAvatarNameCache +class LLAvatarNameCache : public LLSingleton { + LLSINGLETON(LLAvatarNameCache); + ~LLAvatarNameCache(); +public: typedef boost::signals2::signal use_display_name_signal_t; - // Until the cache is set running, immediate lookups will fail and - // async lookups will be queued. This allows us to block requests - // until we know if the first region supports display names. - void initClass(bool running, bool usePeopleAPI); - void cleanupClass(); - // Import/export the name cache to file. bool importFile(std::istream& istr); void exportFile(std::ostream& ostr); @@ -55,6 +54,7 @@ namespace LLAvatarNameCache // Do we have a valid lookup URL, i.e. are we trying to use the // more recent display name lookup system? bool hasNameLookupURL(); + void setUsePeopleAPI(bool use_api); bool usePeopleAPI(); // Periodically makes a batch request for display names not already in @@ -63,7 +63,8 @@ namespace LLAvatarNameCache // If name is in cache, returns true and fills in provided LLAvatarName // otherwise returns false. - bool get(const LLUUID& agent_id, LLAvatarName *av_name); + static bool get(const LLUUID& agent_id, LLAvatarName *av_name); + bool getName(const LLUUID& agent_id, LLAvatarName *av_name); // Callback types for get() below typedef boost::signals2::signal< @@ -74,7 +75,8 @@ namespace LLAvatarNameCache // Fetches name information and calls callbacks. // If name information is in cache, callbacks will be called immediately. - callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); + static callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); + callback_connection_t getNameCallback(const LLUUID& agent_id, callback_slot_t slot); // Set display name: flips the switch and triggers the callbacks. void setUseDisplayNames(bool use); @@ -100,7 +102,83 @@ namespace LLAvatarNameCache F64 nameExpirationFromHeaders(const LLSD& headers); void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); -} + +private: + // Handle name response off network. + void processName(const LLUUID& agent_id, + const LLAvatarName& av_name); + + void requestNamesViaCapability(); + + // Legacy name system callbacks + static void legacyNameCallback(const LLUUID& agent_id, + const std::string& full_name, + bool is_group); + static void legacyNameFetch(const LLUUID& agent_id, + const std::string& full_name, + bool is_group); + + void requestNamesViaLegacy(); + + // Do a single callback to a given slot + void fireSignal(const LLUUID& agent_id, + const callback_slot_t& slot, + const LLAvatarName& av_name); + + // Is a request in-flight over the network? + bool isRequestPending(const LLUUID& agent_id); + + // Erase expired names from cache + void eraseUnrefreshed(); + + bool expirationFromCacheControl(const LLSD& headers, F64 *expires); + + // This is a coroutine. + static void requestAvatarNameCache_(std::string url, std::vector agentIds); + + void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult); + +private: + + use_display_name_signal_t mUseDisplayNamesSignal; + + // Cache starts in a paused state until we can determine if the + // current region supports display names. + bool mRunning; + + // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false. + // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer). + bool mUsePeopleAPI; + + // Base lookup URL for name service. + // On simulator, loaded from indra.xml + // On viewer, usually a simulator capability (at People API team's request) + // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/" + std::string mNameLookupURL; + + // Accumulated agent IDs for next query against service + typedef std::set ask_queue_t; + ask_queue_t mAskQueue; + + // Agent IDs that have been requested, but with no reply. + // Maps agent ID to frame time request was made. + typedef std::map pending_queue_t; + pending_queue_t mPendingQueue; + + // Callbacks to fire when we received a name. + // May have multiple callbacks for a single ID, which are + // represented as multiple slots bound to the signal. + // Avoid copying signals via pointers. + typedef std::map signal_map_t; + signal_map_t mSignalMap; + + // The cache at last, i.e. avatar names we know about. + typedef std::map cache_t; + cache_t mCache; + + // Time when unrefreshed cached names were checked last. + F64 mLastExpireCheck; +}; // Parse a cache-control header to get the max-age delta-seconds. // Returns true if header has max-age param and it parses correctly. -- cgit v1.3 From adb3f447b33e42bdb6e4a5a1ac79eebd862dafb4 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 10 Aug 2019 20:33:59 -0400 Subject: DRTVWR-493: Introduce test catch_what(), catch_llerrs() functions. Use them in place of awkward try/catch test boilerplate. --- indra/llcommon/tests/lleventcoro_test.cpp | 33 ++++------ indra/llcommon/tests/lleventdispatcher_test.cpp | 83 +++++++------------------ indra/llcommon/tests/lleventfilter_test.cpp | 12 +--- indra/llcommon/tests/llinstancetracker_test.cpp | 33 +++------- indra/llcommon/tests/lllazy_test.cpp | 13 ++-- indra/llcommon/tests/llleap_test.cpp | 20 +++--- indra/llcommon/tests/llprocess_test.cpp | 16 ++--- indra/llcommon/tests/wrapllerrs.h | 8 +++ indra/llmessage/tests/llareslistener_test.cpp | 48 ++++---------- indra/newview/tests/llxmlrpclistener_test.cpp | 24 ++----- indra/test/catch_and_store_what_in.h | 26 +++++++- indra/test/llevents_tut.cpp | 76 ++++++++++------------ indra/test/test.cpp | 1 - 13 files changed, 146 insertions(+), 247 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index a459d17fb8..ea198849cd 100644 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -506,16 +506,10 @@ namespace tut replyName = waiter.getName0(); errorName = waiter.getName1(); WrapLLErrs capture; - try - { - result = waiter.suspendWithLog(); - debug("no exception"); - } - catch (const WrapLLErrs::FatalException& e) - { - debug(STRINGIZE("exception " << e.what())); - threw = e.what(); - } + threw = catch_llerrs([&waiter, &debug](){ + result = waiter.suspendWithLog(); + debug("no exception"); + }); } END } @@ -762,18 +756,13 @@ namespace tut { LLCoroEventPumps waiter; WrapLLErrs capture; - try - { - result = waiter.postAndSuspendWithLog( - LLSDMap("value", 31)("fail", LLSD()), - immediateAPI.getPump(), "reply", "error"); - debug("no exception"); - } - catch (const WrapLLErrs::FatalException& e) - { - debug(STRINGIZE("exception " << e.what())); - threw = e.what(); - } + threw = catch_llerrs( + [&waiter, &debug](){ + result = waiter.postAndSuspendWithLog( + LLSDMap("value", 31)("fail", LLSD()), + immediateAPI.getPump(), "reply", "error"); + debug("no exception"); + }); } END } diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp index 5a4df81bf1..a181d5c941 100644 --- a/indra/llcommon/tests/lleventdispatcher_test.cpp +++ b/indra/llcommon/tests/lleventdispatcher_test.cpp @@ -22,6 +22,7 @@ #include "llsdutil.h" #include "stringize.h" #include "tests/wrapllerrs.h" +#include "../test/catch_and_store_what_in.h" #include #include @@ -630,16 +631,9 @@ namespace tut void call_exc(const std::string& func, const LLSD& args, const std::string& exc_frag) { - std::string threw; - try - { - work(func, args); - } - catch (const std::runtime_error& e) - { - cout << "*** " << e.what() << '\n'; - threw = e.what(); - } + std::string threw = catch_what([this, &func, &args](){ + work(func, args); + }); ensure_has(threw, exc_frag); } @@ -717,15 +711,9 @@ namespace tut LLSD attempts(LLSDArray(17)(LLSDMap("pi", 3.14)("two", 2))); foreach(LLSD ae, inArray(attempts)) { - std::string threw; - try - { - work.add("freena_err", "freena", freena, ae); - } - catch (const std::exception& e) - { - threw = e.what(); - } + std::string threw = catch_what([this, &ae](){ + work.add("freena_err", "freena", freena, ae); + }); ensure_has(threw, "must be an array"); } } @@ -734,15 +722,9 @@ namespace tut void object::test<2>() { set_test_name("map-style registration with badly-formed defaults"); - std::string threw; - try - { - work.add("freena_err", "freena", freena, LLSDArray("a")("b"), 17); - } - catch (const std::exception& e) - { - threw = e.what(); - } + std::string threw = catch_what([this](){ + work.add("freena_err", "freena", freena, LLSDArray("a")("b"), 17); + }); ensure_has(threw, "must be a map or an array"); } @@ -750,17 +732,11 @@ namespace tut void object::test<3>() { set_test_name("map-style registration with too many array defaults"); - std::string threw; - try - { - work.add("freena_err", "freena", freena, - LLSDArray("a")("b"), - LLSDArray(17)(0.9)("gack")); - } - catch (const std::exception& e) - { - threw = e.what(); - } + std::string threw = catch_what([this](){ + work.add("freena_err", "freena", freena, + LLSDArray("a")("b"), + LLSDArray(17)(0.9)("gack")); + }); ensure_has(threw, "shorter than"); } @@ -768,17 +744,11 @@ namespace tut void object::test<4>() { set_test_name("map-style registration with too many map defaults"); - std::string threw; - try - { - work.add("freena_err", "freena", freena, - LLSDArray("a")("b"), - LLSDMap("b", 17)("foo", 3.14)("bar", "sinister")); - } - catch (const std::exception& e) - { - threw = e.what(); - } + std::string threw = catch_what([this](){ + work.add("freena_err", "freena", freena, + LLSDArray("a")("b"), + LLSDMap("b", 17)("foo", 3.14)("bar", "sinister")); + }); ensure_has(threw, "nonexistent params"); ensure_has(threw, "foo"); ensure_has(threw, "bar"); @@ -1039,16 +1009,9 @@ namespace tut // We don't have a comparable helper function for the one-arg // operator() method, and it's not worth building one just for this // case. Write it out. - std::string threw; - try - { - work(LLSDMap("op", "freek")); - } - catch (const std::runtime_error& e) - { - cout << "*** " << e.what() << "\n"; - threw = e.what(); - } + std::string threw = catch_what([this](){ + work(LLSDMap("op", "freek")); + }); ensure_has(threw, "bad"); ensure_has(threw, "op"); ensure_has(threw, "freek"); diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp index eb98b12ef5..a23abf453e 100644 --- a/indra/llcommon/tests/lleventfilter_test.cpp +++ b/indra/llcommon/tests/lleventfilter_test.cpp @@ -350,15 +350,9 @@ namespace tut // Now let the timer expire. filter.forceTimeout(); // Notice the timeout. - std::string threw; - try - { - mainloop.post(17); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([this](){ + mainloop.post(17); + }); ensure_contains("errorAfter() timeout exception", threw, "timeout"); // Timing out cancels the timer. Verify that. listener0.reset(0); diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index c7d4b8a06b..0fe65f0831 100644 --- a/indra/llcommon/tests/llinstancetracker_test.cpp +++ b/indra/llcommon/tests/llinstancetracker_test.cpp @@ -198,14 +198,9 @@ namespace tut { WrapLLErrs wrapper; Keyed::instance_iter i(Keyed::beginInstances()); - try - { - delete keyed; - } - catch (const WrapLLErrs::FatalException& e) - { - what = e.what(); - } + what = catch_llerrs([&keyed](){ + delete keyed; + }); } ensure(! what.empty()); } @@ -219,14 +214,9 @@ namespace tut { WrapLLErrs wrapper; Keyed::key_iter i(Keyed::beginKeys()); - try - { - delete keyed; - } - catch (const WrapLLErrs::FatalException& e) - { - what = e.what(); - } + what = catch_llerrs([&keyed](){ + delete keyed; + }); } ensure(! what.empty()); } @@ -240,14 +230,9 @@ namespace tut { WrapLLErrs wrapper; Unkeyed::instance_iter i(Unkeyed::beginInstances()); - try - { - delete unkeyed; - } - catch (const WrapLLErrs::FatalException& e) - { - what = e.what(); - } + what = catch_llerrs([&unkeyed](){ + delete unkeyed; + }); } ensure(! what.empty()); } diff --git a/indra/llcommon/tests/lllazy_test.cpp b/indra/llcommon/tests/lllazy_test.cpp index 32a717f4fc..542306ee22 100644 --- a/indra/llcommon/tests/lllazy_test.cpp +++ b/indra/llcommon/tests/lllazy_test.cpp @@ -38,6 +38,7 @@ #include // other Linden headers #include "../test/lltut.h" +#include "../test/catch_and_store_what_in.h" namespace bll = boost::lambda; @@ -200,15 +201,9 @@ namespace tut void lllazy_object::test<2>() { TestNeedsTesting tnt; - std::string threw; - try - { - tnt.toolate(); - } - catch (const LLLazyCommon::InstanceChange& e) - { - threw = e.what(); - } + std::string threw = catch_what([&tnt](){ + tnt.toolate(); + }); ensure_contains("InstanceChange exception", threw, "replace LLLazy instance"); } diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index 45648536c4..bf0a74d10d 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -23,7 +23,7 @@ #include "../test/lltut.h" #include "../test/namedtempfile.h" #include "../test/catch_and_store_what_in.h" -#include "wrapllerrs.h" +#include "wrapllerrs.h" // CaptureLog #include "llevents.h" #include "llprocess.h" #include "llstring.h" @@ -290,12 +290,9 @@ namespace tut void object::test<6>() { set_test_name("empty plugin vector"); - std::string threw; - try - { - LLLeap::create("empty", StringVec()); - } - CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error) + std::string threw = catch_what([](){ + LLLeap::create("empty", StringVec()); + }); ensure_contains("LLLeap::Error", threw, "no plugin"); // try the suppress-exception variant ensure("bad launch returned non-NULL", ! LLLeap::create("empty", StringVec(), false)); @@ -308,12 +305,9 @@ namespace tut // Synthesize bogus executable name std::string BADPYTHON(PYTHON.substr(0, PYTHON.length()-1) + "x"); CaptureLog log; - std::string threw; - try - { - LLLeap::create("bad exe", BADPYTHON); - } - CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error) + std::string threw = catch_what([&BADPYTHON](){ + LLLeap::create("bad exe", BADPYTHON); + }); ensure_contains("LLLeap::create() didn't throw", threw, "failed"); log.messageWith("failed"); log.messageWith(BADPYTHON); diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 5c87cdabd9..222d832084 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -25,8 +25,6 @@ #include #include #include -//#include -//#include // other Linden headers #include "../test/lltut.h" #include "../test/namedtempfile.h" @@ -35,7 +33,7 @@ #include "llsdutil.h" #include "llevents.h" #include "llstring.h" -#include "wrapllerrs.h" +#include "wrapllerrs.h" // CaptureLog #if defined(LL_WINDOWS) #define sleep(secs) _sleep((secs) * 1000) @@ -45,8 +43,7 @@ #include #endif -//namespace lambda = boost::lambda; - std::string apr_strerror_helper(apr_status_t rv) +std::string apr_strerror_helper(apr_status_t rv) { char errbuf[256]; apr_strerror(rv, errbuf, sizeof(errbuf)); @@ -960,12 +957,9 @@ namespace tut #define CATCH_IN(THREW, EXCEPTION, CODE) \ do \ { \ - (THREW).clear(); \ - try \ - { \ - CODE; \ - } \ - CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \ + (THREW) = catch_what([&](){ \ + CODE; \ + }); \ ensure("failed to throw " #EXCEPTION ": " #CODE, ! (THREW).empty()); \ } while (0) diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 08fbf19b1c..3fb79f6b5d 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -37,6 +37,7 @@ #include "llerrorcontrol.h" #include "llexception.h" #include "stringize.h" +#include "../test/catch_and_store_what_in.h" #include #include #include @@ -86,6 +87,13 @@ struct WrapLLErrs LLError::FatalFunction mPriorFatal; }; +/// Convenience wrapper for catch_what() +template +std::string catch_llerrs(FUNC func) +{ + return catch_what(func); +} + /** * Capture log messages. This is adapted (simplified) from the one in * llerror_test.cpp. diff --git a/indra/llmessage/tests/llareslistener_test.cpp b/indra/llmessage/tests/llareslistener_test.cpp index c04696c86b..8e5bcd326c 100644 --- a/indra/llmessage/tests/llareslistener_test.cpp +++ b/indra/llmessage/tests/llareslistener_test.cpp @@ -138,15 +138,9 @@ namespace tut WrapLLErrs capture; LLSD request; request["op"] = "foo"; - std::string threw; - try - { - LLEventPumps::instance().obtain("LLAres").post(request); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([&request](){ + LLEventPumps::instance().obtain("LLAres").post(request); + }); ensure_contains("LLAresListener bad op", threw, "bad"); } @@ -157,15 +151,9 @@ namespace tut WrapLLErrs capture; LLSD request; request["op"] = "rewriteURI"; - std::string threw; - try - { - LLEventPumps::instance().obtain("LLAres").post(request); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([&request](){ + LLEventPumps::instance().obtain("LLAres").post(request); + }); ensure_contains("LLAresListener bad req", threw, "missing"); ensure_contains("LLAresListener bad req", threw, "reply"); ensure_contains("LLAresListener bad req", threw, "uri"); @@ -179,15 +167,9 @@ namespace tut LLSD request; request["op"] = "rewriteURI"; request["reply"] = "nonexistent"; - std::string threw; - try - { - LLEventPumps::instance().obtain("LLAres").post(request); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([&request](){ + LLEventPumps::instance().obtain("LLAres").post(request); + }); ensure_contains("LLAresListener bad req", threw, "missing"); ensure_contains("LLAresListener bad req", threw, "uri"); ensure_does_not_contain("LLAresListener bad req", threw, "reply"); @@ -201,15 +183,9 @@ namespace tut LLSD request; request["op"] = "rewriteURI"; request["uri"] = "foo.bar.com"; - std::string threw; - try - { - LLEventPumps::instance().obtain("LLAres").post(request); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([&request](){ + LLEventPumps::instance().obtain("LLAres").post(request); + }); ensure_contains("LLAresListener bad req", threw, "missing"); ensure_contains("LLAresListener bad req", threw, "reply"); ensure_does_not_contain("LLAresListener bad req", threw, "uri"); diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp index 6e9756e7d5..f9a4ec373a 100644 --- a/indra/newview/tests/llxmlrpclistener_test.cpp +++ b/indra/newview/tests/llxmlrpclistener_test.cpp @@ -88,15 +88,9 @@ namespace tut WrapLLErrs capture; LLSD request; request["uri"] = uri; - std::string threw; - try - { - pumps.obtain("LLXMLRPCTransaction").post(request); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([&pumps, &request](){ + pumps.obtain("LLXMLRPCTransaction").post(request); + }); ensure_contains("threw exception", threw, "missing params"); ensure_contains("identified missing", threw, "method"); ensure_contains("identified missing", threw, "reply"); @@ -113,15 +107,9 @@ namespace tut request["reply"] = "reply"; LLSD& params(request["params"]); params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params - std::string threw; - try - { - pumps.obtain("LLXMLRPCTransaction").post(request); - } - catch (const WrapLLErrs::FatalException& e) - { - threw = e.what(); - } + std::string threw = catch_llerrs([&pumps, &request](){ + pumps.obtain("LLXMLRPCTransaction").post(request); + }); ensure_contains("threw exception", threw, "unknown type"); } diff --git a/indra/test/catch_and_store_what_in.h b/indra/test/catch_and_store_what_in.h index 59f8cc0085..5beba06024 100644 --- a/indra/test/catch_and_store_what_in.h +++ b/indra/test/catch_and_store_what_in.h @@ -2,7 +2,7 @@ * @file catch_and_store_what_in.h * @author Nat Goodspeed * @date 2012-02-15 - * @brief CATCH_AND_STORE_WHAT_IN() macro + * @brief catch_what() template function, CATCH_AND_STORE_WHAT_IN() macro * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Copyright (c) 2012, Linden Research, Inc. @@ -12,6 +12,30 @@ #if ! defined(LL_CATCH_AND_STORE_WHAT_IN_H) #define LL_CATCH_AND_STORE_WHAT_IN_H +/** + * In the brave new world of lambdas, we can use a nicer C++ idiom for testing + * exceptions than CATCH_AND_STORE_WHAT_IN() below, e.g.: + * + * @code + * std::string threw = catch_what( + * [](){ throw std::runtime_error("badness"); }); + * ensure_equals(threw, "badness"); + * @endcode + */ +template +std::string catch_what(FUNC func) +{ + try + { + func(); + return {}; + } + catch (const EXCEPTION& err) + { + return err.what(); + } +} + /** * Idiom useful for test programs: catch an expected exception, store its * what() string in a specified std::string variable. From there the caller diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp index 16edab6282..3abae3e43e 100644 --- a/indra/test/llevents_tut.cpp +++ b/indra/test/llevents_tut.cpp @@ -134,17 +134,15 @@ void events_object::test<1>() per_frame.post(4); check_listener("re-blocked", listener0, 3); } // unblock - std::string threw; - try - { - // NOTE: boost::bind() saves its arguments by VALUE! If you pass - // an object instance rather than a pointer, you'll end up binding - // to an internal copy of that instance! Use boost::ref() to - // capture a reference instead. - per_frame.listen(listener0.getName(), // note bug, dup name - boost::bind(&Listener::call, boost::ref(listener1), _1)); - } - CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupListenerName) + std::string threw = catch_what( + [&per_frame, this](){ + // NOTE: boost::bind() saves its arguments by VALUE! If you pass + // an object instance rather than a pointer, you'll end up binding + // to an internal copy of that instance! Use boost::ref() to + // capture a reference instead. + per_frame.listen(listener0.getName(), // note bug, dup name + boost::bind(&Listener::call, boost::ref(listener1), _1)); + }); ensure_equals(threw, std::string("DupListenerName: " "Attempt to register duplicate listener name '") + @@ -341,15 +339,13 @@ void events_object::test<7>() ensure_equals(collector.result, make(list_of("Mary")("spot")("checked"))); collector.clear(); button.stopListening("spot"); - std::string threw; - try - { - button.listen("spot", - boost::bind(&Collect::add, boost::ref(collector), "spot", _1), - // after "Mary" and "checked" -- whoops! - make(list_of("Mary")("checked"))); - } - CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::Cycle) + std::string threw = catch_what( + [&button, &collector](){ + button.listen("spot", + boost::bind(&Collect::add, boost::ref(collector), "spot", _1), + // after "Mary" and "checked" -- whoops! + make(list_of("Mary")("checked"))); + }); // Obviously the specific wording of the exception text can // change; go ahead and change the test to match. // Establish that it contains: @@ -374,15 +370,13 @@ void events_object::test<7>() button.post(3); ensure_equals(collector.result, make(list_of("Mary")("checked")("yellow")("shoelaces"))); collector.clear(); - threw.clear(); - try - { - button.listen("of", - boost::bind(&Collect::add, boost::ref(collector), "of", _1), - make(list_of("shoelaces")), - make(list_of("yellow"))); - } - CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::OrderChange) + threw = catch_what( + [&button, &collector](){ + button.listen("of", + boost::bind(&Collect::add, boost::ref(collector), "of", _1), + make(list_of("shoelaces")), + make(list_of("yellow"))); + }); // Same remarks about the specific wording of the exception. Just // ensure that it contains enough information to clarify the // problem and what must be done to resolve it. @@ -404,13 +398,11 @@ void events_object::test<8>() { // nested scope // Hand-instantiate an LLEventStream... LLEventStream bob("bob"); - std::string threw; - try - { - // then another with a duplicate name. - LLEventStream bob2("bob"); - } - CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName) + std::string threw = catch_what( + [](){ + // then another with a duplicate name. + LLEventStream bob2("bob"); + }); ensure("Caught DupPumpName", !threw.empty()); } // delete first 'bob' LLEventStream bob("bob"); // should work, previous one unregistered @@ -445,13 +437,11 @@ void events_object::test<9>() listener0.listenTo(random); eventSource("random"); check_listener("got by pump name", listener0, 17); - std::string threw; - try - { - LLListenerOrPumpName empty; - empty(17); - } - CATCH_AND_STORE_WHAT_IN(threw, LLListenerOrPumpName::Empty) + std::string threw = catch_what( + [](){ + LLListenerOrPumpName empty; + empty(17); + }); ensure("threw Empty", !threw.empty()); } diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 861ec1d942..d4cd4b951e 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -37,7 +37,6 @@ #include "linden_common.h" #include "llerrorcontrol.h" #include "lltut.h" -#include "tests/wrapllerrs.h" // RecorderProxy #include "stringize.h" #include "namedtempfile.h" #include "lltrace.h" -- cgit v1.3 From f0fa4f94a5400fe5d21cf5bf7570129916bf9787 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 12 Aug 2019 08:26:51 -0400 Subject: DRTVWR-493: Make catch_llerrs() a member of WrapLLErrs. --- indra/llcommon/tests/lleventcoro_test.cpp | 4 ++-- indra/llcommon/tests/lleventfilter_test.cpp | 2 +- indra/llcommon/tests/llinstancetracker_test.cpp | 6 ++--- indra/llcommon/tests/wrapllerrs.h | 32 +++++++++++++++++++------ indra/llmessage/tests/llareslistener_test.cpp | 8 +++---- indra/newview/tests/llxmlrpclistener_test.cpp | 4 ++-- 6 files changed, 37 insertions(+), 19 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index ea198849cd..fa02d2bb1a 100644 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -506,7 +506,7 @@ namespace tut replyName = waiter.getName0(); errorName = waiter.getName1(); WrapLLErrs capture; - threw = catch_llerrs([&waiter, &debug](){ + threw = capture.catch_llerrs([&waiter, &debug](){ result = waiter.suspendWithLog(); debug("no exception"); }); @@ -756,7 +756,7 @@ namespace tut { LLCoroEventPumps waiter; WrapLLErrs capture; - threw = catch_llerrs( + threw = capture.catch_llerrs( [&waiter, &debug](){ result = waiter.postAndSuspendWithLog( LLSDMap("value", 31)("fail", LLSD()), diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp index a23abf453e..1875013794 100644 --- a/indra/llcommon/tests/lleventfilter_test.cpp +++ b/indra/llcommon/tests/lleventfilter_test.cpp @@ -350,7 +350,7 @@ namespace tut // Now let the timer expire. filter.forceTimeout(); // Notice the timeout. - std::string threw = catch_llerrs([this](){ + std::string threw = capture.catch_llerrs([this](){ mainloop.post(17); }); ensure_contains("errorAfter() timeout exception", threw, "timeout"); diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index 0fe65f0831..d94fc0c56d 100644 --- a/indra/llcommon/tests/llinstancetracker_test.cpp +++ b/indra/llcommon/tests/llinstancetracker_test.cpp @@ -198,7 +198,7 @@ namespace tut { WrapLLErrs wrapper; Keyed::instance_iter i(Keyed::beginInstances()); - what = catch_llerrs([&keyed](){ + what = wrapper.catch_llerrs([&keyed](){ delete keyed; }); } @@ -214,7 +214,7 @@ namespace tut { WrapLLErrs wrapper; Keyed::key_iter i(Keyed::beginKeys()); - what = catch_llerrs([&keyed](){ + what = wrapper.catch_llerrs([&keyed](){ delete keyed; }); } @@ -230,7 +230,7 @@ namespace tut { WrapLLErrs wrapper; Unkeyed::instance_iter i(Unkeyed::beginInstances()); - what = catch_llerrs([&unkeyed](){ + what = wrapper.catch_llerrs([&unkeyed](){ delete unkeyed; }); } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 3fb79f6b5d..b07d5afbd8 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -82,18 +82,36 @@ struct WrapLLErrs LLTHROW(FatalException(message)); } + /// Convenience wrapper for catch_what() + // + // The implementation makes it clear that this function need not be a + // member; it could easily be a free function. It is a member because it + // makes no sense to attempt to catch FatalException unless there is a + // WrapLLErrs instance in scope. Without a live WrapLLErrs instance, any + // LL_ERRS() reached by code within 'func' would terminate the test + // program instead of throwing FatalException. + // + // We were tempted to introduce a free function, likewise accepting + // arbitrary 'func', that would instantiate WrapLLErrs and then call + // catch_llerrs() on that instance. We decided against it, for this + // reason: on extending a test function containing a single call to that + // free function, a maintainer would most likely make additional calls to + // that free function, instead of switching to an explicit WrapLLErrs + // declaration with several calls to its catch_llerrs() member function. + // Even a construct such as WrapLLErrs().catch_llerrs(...) would make the + // object declaration more visible; it's not unreasonable to expect a + // maintainer to extend that by naming and reusing the WrapLLErrs instance. + template + std::string catch_llerrs(FUNC func) + { + return catch_what(func); + } + std::string error; LLError::SettingsStoragePtr mPriorErrorSettings; LLError::FatalFunction mPriorFatal; }; -/// Convenience wrapper for catch_what() -template -std::string catch_llerrs(FUNC func) -{ - return catch_what(func); -} - /** * Capture log messages. This is adapted (simplified) from the one in * llerror_test.cpp. diff --git a/indra/llmessage/tests/llareslistener_test.cpp b/indra/llmessage/tests/llareslistener_test.cpp index 8e5bcd326c..254185cbd0 100644 --- a/indra/llmessage/tests/llareslistener_test.cpp +++ b/indra/llmessage/tests/llareslistener_test.cpp @@ -138,7 +138,7 @@ namespace tut WrapLLErrs capture; LLSD request; request["op"] = "foo"; - std::string threw = catch_llerrs([&request](){ + std::string threw = capture.catch_llerrs([&request](){ LLEventPumps::instance().obtain("LLAres").post(request); }); ensure_contains("LLAresListener bad op", threw, "bad"); @@ -151,7 +151,7 @@ namespace tut WrapLLErrs capture; LLSD request; request["op"] = "rewriteURI"; - std::string threw = catch_llerrs([&request](){ + std::string threw = capture.catch_llerrs([&request](){ LLEventPumps::instance().obtain("LLAres").post(request); }); ensure_contains("LLAresListener bad req", threw, "missing"); @@ -167,7 +167,7 @@ namespace tut LLSD request; request["op"] = "rewriteURI"; request["reply"] = "nonexistent"; - std::string threw = catch_llerrs([&request](){ + std::string threw = capture.catch_llerrs([&request](){ LLEventPumps::instance().obtain("LLAres").post(request); }); ensure_contains("LLAresListener bad req", threw, "missing"); @@ -183,7 +183,7 @@ namespace tut LLSD request; request["op"] = "rewriteURI"; request["uri"] = "foo.bar.com"; - std::string threw = catch_llerrs([&request](){ + std::string threw = capture.catch_llerrs([&request](){ LLEventPumps::instance().obtain("LLAres").post(request); }); ensure_contains("LLAresListener bad req", threw, "missing"); diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp index f9a4ec373a..dbaae7280c 100644 --- a/indra/newview/tests/llxmlrpclistener_test.cpp +++ b/indra/newview/tests/llxmlrpclistener_test.cpp @@ -88,7 +88,7 @@ namespace tut WrapLLErrs capture; LLSD request; request["uri"] = uri; - std::string threw = catch_llerrs([&pumps, &request](){ + std::string threw = capture.catch_llerrs([&pumps, &request](){ pumps.obtain("LLXMLRPCTransaction").post(request); }); ensure_contains("threw exception", threw, "missing params"); @@ -107,7 +107,7 @@ namespace tut request["reply"] = "reply"; LLSD& params(request["params"]); params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params - std::string threw = catch_llerrs([&pumps, &request](){ + std::string threw = capture.catch_llerrs([&pumps, &request](){ pumps.obtain("LLXMLRPCTransaction").post(request); }); ensure_contains("threw exception", threw, "unknown type"); -- cgit v1.3 From e1451bb1d1df2c122874d3962b1a91cb6a913ca3 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 4 Sep 2019 20:56:45 +0300 Subject: DRTVWR-493 Do not recreate proxy only to destroy it --- indra/llmessage/llproxy.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 5730a36267..eefac1de21 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -403,8 +403,11 @@ LLSocks5AuthType LLProxy::getSelectedAuthMethod() const //static void LLProxy::cleanupClass() { - getInstance()->stopSOCKSProxy(); - deleteSingleton(); + if (instanceExists()) + { + getInstance()->stopSOCKSProxy(); + deleteSingleton(); + } } /** -- cgit v1.3