Skip to content

Performance optimizations to resolve long stalls - #5393

Merged
akleshchev merged 2 commits into
developfrom
andreyk/viewer_5356
Feb 11, 2026
Merged

Performance optimizations to resolve long stalls#5393
akleshchev merged 2 commits into
developfrom
andreyk/viewer_5356

Conversation

@akleshchev

Copy link
Copy Markdown
Contributor
  1. Inventory was parsing a large message for over a second, moved that to a thread worker.
  2. Fast cache was locked from accessing id map by texture thread on a general cache mutex. Added map specific mutex.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets viewer stalls by offloading expensive HTTP response parsing from the main thread and reducing lock contention in the texture cache by introducing a more granular mutex for header ID map access.

Changes:

  • Added a dedicated mutex for LLTextureCache::mHeaderIDMap and updated call sites to lock the ID map independently of the broader header mutex.
  • Updated LLCoreHttpUtil::HttpCoroHandler to post large-body success-response parsing to the "General" WorkQueue, replying back on "mainloop".
  • Refactored portions of HttpCoroHandler (const-correctness and shared reply posting) to support the threaded parsing flow.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
indra/newview/lltexturecache.h Introduces mHeaderIDMapMutex to support finer-grained locking for the header ID map.
indra/newview/lltexturecache.cpp Switches mHeaderIDMap accesses to use the new mutex to reduce contention and stalls.
indra/llmessage/llcorehttputil.h Extends HttpCoroHandler to support shared_from_this() and updates virtual method constness to align with new flow.
indra/llmessage/llcorehttputil.cpp Adds WorkQueue-based off-main-thread parsing for large HTTP success bodies and centralizes reply posting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread indra/llmessage/llcorehttputil.cpp
Comment on lines +311 to +333
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();
});

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This posts a std::pair<LLSD, HttpStatus> through WorkQueue::postTo(), which internally copies the posted std::function into the queue; that implies copying/moving LLSD across threads. llsd.h explicitly warns that copying/sharing LLSD across threads is unsafe and requires special ownership-transfer patterns. To avoid LLSD cross-thread copies, return a thread-safe wrapper (e.g., std::shared_ptr<LLSD> / heap-allocated LLSD with ownership transfer) or serialize the parsed result into a thread-safe form for transport back to the main thread.

Copilot uses AI. Check for mistakes.

@akleshchev akleshchev Feb 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::shared_ptr wouldn't help as LLSD consists of multiple insecure elements, wrapping each is not practical, serializing LLSD won't help either as it is huge, deserializing will cause a stall.

As I understant it, before callback gets executed, usage of response's llsd should already be cleaned up and the std::pair should be moved, not copied. If that isn't the case and there will be problems I will figure something out. Perhaps LLSD can be stored in the handler and be mutex protected.

try
constexpr size_t MAX_BODY_SIZE_THRESHOLD = 65536;
bool posted = false;
// Some messsages (ex: AISAPI) can return large bodies.

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling: "messsages" -> "messages".

Suggested change
// Some messsages (ex: AISAPI) can return large bodies.
// Some messages (ex: AISAPI) can return large bodies.

Copilot uses AI. Check for mistakes.
Comment thread indra/llmessage/llcorehttputil.cpp
@akleshchev
akleshchev merged commit 6be26a0 into develop Feb 11, 2026
21 checks passed
@akleshchev
akleshchev deleted the andreyk/viewer_5356 branch February 11, 2026 01:29
@github-actions github-actions Bot locked and limited conversation to collaborators Feb 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve performance when parsing a very large message from server into llsd

4 participants