diff options
Diffstat (limited to 'indra/llmessage')
| -rw-r--r-- | indra/llmessage/llavatarnamecache.cpp | 18 | ||||
| -rw-r--r-- | indra/llmessage/llavatarnamecache.h | 10 | ||||
| -rw-r--r-- | indra/llmessage/llcachename.cpp | 15 | ||||
| -rw-r--r-- | indra/llmessage/llcachename.h | 3 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 132 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.h | 9 |
6 files changed, 123 insertions, 64 deletions
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index ebafc53a4d..86b36315dc 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -276,7 +276,7 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h // Provide some fallback for agents that return errors void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) { - std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id); + cache_t::iterator existing = mCache.find(agent_id); if (existing == mCache.end()) { // there is no existing cache entry, so make a temporary name from legacy @@ -311,7 +311,7 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& bool updated_account = true; // assume obsolete value for new arrivals by default - std::map<LLUUID, LLAvatarName>::iterator it = mCache.find(agent_id); + cache_t::iterator it = mCache.find(agent_id); if (it != mCache.end() && (*it).second.getAccountName() == av_name.getAccountName()) { @@ -418,7 +418,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<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id); + cache_t::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id); LLAvatarName& av_name = av_record->second; av_name.setExpires(MAX_UNREFRESHED_TIME); } @@ -631,7 +631,7 @@ bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name) if (mRunning) { // ...only do immediate lookups when cache is running - std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); + cache_t::iterator it = mCache.find(agent_id); if (it != mCache.end()) { *av_name = it->second; @@ -682,7 +682,7 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(cons if (mRunning) { // ...only do immediate lookups when cache is running - std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); + cache_t::iterator it = mCache.find(agent_id); if (it != mCache.end()) { const LLAvatarName& av_name = it->second; @@ -753,13 +753,11 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na LLUUID LLAvatarNameCache::findIdByName(const std::string& name) { - std::map<LLUUID, LLAvatarName>::iterator it; - std::map<LLUUID, LLAvatarName>::iterator end = mCache.end(); - for (it = mCache.begin(); it != end; ++it) + for (const auto& [id, avatar_name] : mCache) { - if (it->second.getUserName() == name) + if (avatar_name.getUserName() == name) { - return it->first; + return id; } } diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 0ddaee2aa1..6743943495 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -30,8 +30,10 @@ #include "llavatarname.h" // for convenience #include "llsingleton.h" +#include "lluuid.h" #include <boost/signals2.hpp> #include <set> +#include <unordered_map> class LLSD; class LLUUID; @@ -161,23 +163,23 @@ private: std::string mNameLookupURL; // Accumulated agent IDs for next query against service - typedef std::set<LLUUID> ask_queue_t; + using ask_queue_t = std::set<LLUUID>; 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<LLUUID, F64> pending_queue_t; + using pending_queue_t = std::unordered_map<LLUUID, F64>; 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<LLUUID, callback_signal_t*> signal_map_t; + using signal_map_t = std::unordered_map<LLUUID, callback_signal_t*>; signal_map_t mSignalMap; // The cache at last, i.e. avatar names we know about. - typedef std::map<LLUUID, LLAvatarName> cache_t; + using cache_t = std::unordered_map<LLUUID, LLAvatarName>; cache_t mCache; // Time when unrefreshed cached names were checked last. diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 56dfaef873..95b7bb8c3d 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -179,12 +179,11 @@ void ReplySender::flush() } } - -typedef std::set<LLUUID> AskQueue; -typedef std::list<PendingReply*> ReplyQueue; -typedef std::map<LLUUID,U32> PendingQueue; -typedef std::map<LLUUID, LLCacheNameEntry*> Cache; -typedef std::map<std::string, LLUUID> ReverseCache; +using AskQueue = std::set<LLUUID>; +using ReplyQueue = std::list<PendingReply*>; +using PendingQueue = std::unordered_map<LLUUID, U32>; +using Cache = std::unordered_map<LLUUID, LLCacheNameEntry*>; +using ReverseCache = std::unordered_map<std::string, LLUUID>; class LLCacheName::Impl { @@ -214,7 +213,7 @@ public: Impl(LLMessageSystem* msg); ~Impl(); - bool getName(const LLUUID& id, std::string& first, std::string& last, std::map<std::string, std::string>& default_names); + bool getName(const LLUUID& id, std::string& first, std::string& last, cache_map_t& default_names); boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); void addPending(const LLUUID& id, const LLHost& host); @@ -401,7 +400,7 @@ void LLCacheName::exportFile(std::ostream& ostr) } -bool LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last, std::map<std::string, std::string>& default_names) +bool LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last, cache_map_t &default_names) { if(id.isNull()) { diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index 609387b6de..a333eac0f5 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -136,7 +136,8 @@ public: void localizeCacheName(std::string key, std::string value); private: - std::map<std::string, std::string> mCacheName; + using cache_map_t = std::unordered_map<std::string, std::string>; + cache_map_t mCacheName; class Impl; Impl& impl; diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index b24e5e4fcc..647064f607 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -37,6 +37,7 @@ #include "llsdserialize.h" #include "boost/json.hpp" // Boost.Json #include "llfilesystem.h" +#include "workqueue.h" #include "message.h" // for getting the port @@ -295,41 +296,73 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons } else { - try + constexpr size_t MAX_BODY_SIZE_THRESHOLD = 65536; + bool posted = false; + // Some messsages (ex: AISAPI) can return large bodies. + // If the body is larger than our threshold, post the + // parsing to the general queue to avoid stalling the + // main thread. + if (response->getBodySize() > MAX_BODY_SIZE_THRESHOLD) { - result = this->handleSuccess(response, status); - } - catch (std::bad_alloc&) - { - LLError::LLUserWarningMsg::showOutOfMemory(); - LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL; - } - } + response->addRef(); - buildStatusEntry(response, status, result); + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + posted = main_queue->postTo( + general_queue, + [handler = shared_from_this(), response, status]() // Work done on general queue + { + std::pair<LLSD, LLCore::HttpStatus> result; + result.second = status; + try + { + result.first = handler->handleSuccess(response, result.second); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling (threaded)." << LL_ENDL; + } + // LLSD is not thread safe! Be carefull with moving the result around. + return result; + }, + [handler = shared_from_this(), response](std::pair<LLSD, LLCore::HttpStatus> result) mutable // Callback to main thread + { + handler->replyPost(response, result.second, result.first); + response->release(); + }); - if (!status) - { - LLSD &httpStatus = result[HttpCoroutineAdapter::HTTP_RESULTS]; + if (posted) + { + // Thread will do the cleanup and notify the pump. Done. + return; + } + else + { + // For whatever reason, failed to post, clean up and + // do the work on the main thread. + response->release(); + } + } - LLCore::BufferArray *body = response->getBody(); - LLCore::BufferArrayStream bas(body); - LLSD::String bodyData; - bodyData.reserve(response->getBodySize()); - bas >> std::noskipws; - bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>()); - httpStatus["error_body"] = LLSD(bodyData); - if (getBoolSetting(HTTP_LOGBODY_KEY)) + if (!posted) { - // commenting out, but keeping since this can be useful for debugging - LL_WARNS("CoreHTTP") << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL; + try + { + result = this->handleSuccess(response, status); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL; + } } } - mReplyPump.post(result); + replyPost(response, status, result); } -void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result) +void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result) const { LLSD httpresults = LLSD::emptyMap(); @@ -357,6 +390,31 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H result[HttpCoroutineAdapter::HTTP_RESULTS] = httpresults; } +void HttpCoroHandler::replyPost(LLCore::HttpResponse* response, LLCore::HttpStatus &status, LLSD& result) +{ + buildStatusEntry(response, status, result); + + if (!status) + { + LLSD& httpStatus = result[HttpCoroutineAdapter::HTTP_RESULTS]; + + LLCore::BufferArray* body = response->getBody(); + LLCore::BufferArrayStream bas(body); + LLSD::String bodyData; + bodyData.reserve(response->getBodySize()); + bas >> std::noskipws; + bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>()); + httpStatus["error_body"] = LLSD(bodyData); + if (getBoolSetting(HTTP_LOGBODY_KEY)) + { + // commenting out, but keeping since this can be useful for debugging + LL_WARNS("CoreHTTP") << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL; + } + } + + mReplyPump.post(result); +} + void HttpCoroHandler::writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result) { result[HttpCoroutineAdapter::HTTP_RESULTS_SUCCESS] = static_cast<LLSD::Boolean>(status); @@ -389,8 +447,8 @@ public: HttpCoroLLSDHandler(LLEventStream &reply); protected: - virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status); - virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success); + virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const; + virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const; }; //------------------------------------------------------------------------- @@ -400,7 +458,7 @@ HttpCoroLLSDHandler::HttpCoroLLSDHandler(LLEventStream &reply): } -LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) +LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const { LLSD result; @@ -465,7 +523,7 @@ LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore: return result; } -LLSD HttpCoroLLSDHandler::parseBody(LLCore::HttpResponse *response, bool &success) +LLSD HttpCoroLLSDHandler::parseBody(LLCore::HttpResponse *response, bool &success) const { success = true; if (response->getBodySize() == 0) @@ -496,8 +554,8 @@ class HttpCoroRawHandler : public HttpCoroHandler public: HttpCoroRawHandler(LLEventStream &reply); - virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status); - virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success); + virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const; + virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const; }; //------------------------------------------------------------------------- @@ -506,7 +564,7 @@ HttpCoroRawHandler::HttpCoroRawHandler(LLEventStream &reply): { } -LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) +LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const { LLSD result = LLSD::emptyMap(); @@ -552,7 +610,7 @@ LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:: return result; } -LLSD HttpCoroRawHandler::parseBody(LLCore::HttpResponse *response, bool &success) +LLSD HttpCoroRawHandler::parseBody(LLCore::HttpResponse *response, bool &success) const { success = true; return LLSD(); @@ -571,8 +629,8 @@ class HttpCoroJSONHandler : public HttpCoroHandler public: HttpCoroJSONHandler(LLEventStream &reply); - virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status); - virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success); + virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const; + virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const; }; //------------------------------------------------------------------------- @@ -581,7 +639,7 @@ HttpCoroJSONHandler::HttpCoroJSONHandler(LLEventStream &reply) : { } -LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) +LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const { LLSD result = LLSD::emptyMap(); @@ -607,7 +665,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore: return result; } -LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &success) +LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &success) const { success = true; BufferArray * body(response->getBody()); diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 3dbfd6f00d..3072f78911 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -259,7 +259,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ /// +- ["url"] - The URL used to make the call. /// +- ["headers"] - A map of name name value pairs with the HTTP headers. /// -class HttpCoroHandler : public LLCore::HttpHandler +class HttpCoroHandler : public LLCore::HttpHandler, public std::enable_shared_from_this<HttpCoroHandler> { public: @@ -279,11 +279,12 @@ public: protected: /// this method may modify the status value - virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) = 0; - virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) = 0; + virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const = 0; + virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const = 0; private: - void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result); + void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result) const; + void replyPost(LLCore::HttpResponse* response, LLCore::HttpStatus& status, LLSD& result); LLEventStream &mReplyPump; }; |
