summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/llavatarnamecache.cpp18
-rw-r--r--indra/llmessage/llavatarnamecache.h10
-rw-r--r--indra/llmessage/llcachename.cpp15
-rw-r--r--indra/llmessage/llcachename.h3
-rw-r--r--indra/llmessage/llcorehttputil.cpp132
-rw-r--r--indra/llmessage/llcorehttputil.h9
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;
};