Skip to content

Fix another outfit-related CTD#347

Open
Quinn-Elara wants to merge 4 commits into
AlchemyViewer:developfrom
Quinn-Elara:outfit-fixes-a
Open

Fix another outfit-related CTD#347
Quinn-Elara wants to merge 4 commits into
AlchemyViewer:developfrom
Quinn-Elara:outfit-fixes-a

Conversation

@Quinn-Elara

Copy link
Copy Markdown
Contributor

Description

Defers notifying observers to run on the main thread. This fixes a CTD wherein glyph creation could happen outside of the main thread which would cause a CTD if uncaught.

Related Issues

  • Please link to a relevant GitHub issue for additional context.
    • Bug Fix: Link to an issue that includes reproduction steps and testing guidance.
    • Feature/Enhancement: Link to an issue with a write-up, rationale, and requirements.

Issue Link:


Checklist

Please ensure the following before requesting review:

  • I have provided a clear title and detailed description for this pull request.
  • If useful, I have included media such as screenshots and video to show off my changes.
  • I have tested the changes locally and verified they work as intended.
  • All new and existing tests pass.
  • Code follows the project's style guidelines.
  • Documentation has been updated if needed.
  • Any dependent changes have been merged and published in downstream modules
  • I have reviewed the contributing guidelines.

Additional Notes

Defers notifying observers to run on the main thread. Fixes a CTD wherein glyph creation could happen outside of the main thread which would cause a CTD if uncaught.
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4c003060-b068-4ce9-906c-cb432147c32e

📥 Commits

Reviewing files that changed from the base of the PR and between aa6b43b and f85891c.

📒 Files selected for processing (1)
  • indra/newview/llaisapi.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • indra/newview/llaisapi.cpp

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved inventory observer notifications by deferring them to the main application flow to keep updates consistent and responsive.
    • Reduced redundant notification bursts during large inventory update backlogs by coalescing multiple updates into fewer observer refreshes.
    • Prevented observer updates from firing unexpectedly during object deletion when notifications are explicitly disabled.

Walkthrough

AISUpdate::doUpdate() defers and coalesces inventory observer notifications through the main coroutine. LLInventoryModel::deleteObject() now respects do_notify_observers for pre-removal notifications.

Changes

Inventory notification control

Layer / File(s) Summary
Main coroutine notification dispatch
indra/newview/llaisapi.cpp
Backlog-triggered and final update notifications are dispatched through postToMainCoro(...), with duplicate callbacks coalesced.
Deletion notification guard
indra/newview/llinventorymodel.cpp
The pre-removal observer notification now occurs only when do_notify_observers is enabled.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

I nudged the notices down the lane,
Where main-coro breezes softly remain.
Backlog hops now gather in line,
Delete calls heed the proper sign.
A rabbit thumps: “The timing’s fine!” 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main change: fixing an outfit-related CTD.
Description check ✅ Passed The description follows the template and clearly explains the bug fix, though the issue link is still a placeholder.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@indra/newview/llaisapi.cpp`:
- Around line 1748-1757: Throttle the deferred inventory notifications so they
are posted once per batch instead of once for every overflowed item. In the
inventory fetch/update path around gInventory.notifyObservers() and the
category-create path, add a guard or pending flag so repeated iterations while
mChangedItemIDs remains above MAX_UPDATE_BACKLOG do not queue duplicate
postToMainCoro callbacks. Make sure the same batching logic is applied
consistently in both places that currently defer notifyObservers().
- Around line 1683-1692: The backlog refresh logic in the inventory checks is
repeatedly posting notifyObservers() because deferred execution leaves
gInventory.getChangedIDs().size() above MAX_UPDATE_BACKLOG until the main loop
runs. Add a single pending-refresh/coalescing flag around the backlog paths in
llAisApi so only one deferred inventory refresh can be queued at a time, and
clear that flag when the posted callback runs and notifyObservers() completes.
Apply the same guard to both backlog checks in llAisApi to preserve throttling
and prevent gMainloopWork from being flooded.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5873a2ea-9cbc-418c-a777-28e71e0a6d75

📥 Commits

Reviewing files that changed from the base of the PR and between 341d3c4 and bd86aed.

📒 Files selected for processing (1)
  • indra/newview/llaisapi.cpp

Comment thread indra/newview/llaisapi.cpp
Comment thread indra/newview/llaisapi.cpp
The early notifyObservers() call before tree cleanup was unconditional,
ignoring the do_notify_observers parameter. This caused observers to fire
from non-main coroutines (e.g. the AIS REMOVEITEM coro), which triggered
UI updates and GL texture operations that assert they must run on the main
coroutine.

Deferred notification via idleNotifyObservers() handles the AIS path
correctly on the next main loop tick.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (2)
indra/newview/llaisapi.cpp (2)

1693-1702: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the deferred-notification block into a helper to avoid duplication.

Both backlog paths contain the identical 8-line coalescing block. A small static helper would keep them in sync and reduce maintenance risk if the notification logic changes.

♻️ Proposed helper extraction
+static void postDeferredNotifyObservers()
+{
+    if (!sAISNotifyObserversPending)
+    {
+        sAISNotifyObserversPending = true;
+        LLAppViewer::instance()->postToMainCoro(
+            []()
+            {
+                gInventory.notifyObservers();
+                sAISNotifyObserversPending = false;
+            });
+    }
+}
+
 // ... then at both backlog sites:
-            if (!sAISNotifyObserversPending)
-            {
-                sAISNotifyObserversPending = true;
-                LLAppViewer::instance()->postToMainCoro(
-                    []()
-                    {
-                        gInventory.notifyObservers();
-                        sAISNotifyObserversPending = false;
-                    });
-            }
+            postDeferredNotifyObservers();

Also applies to: 1763-1772

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@indra/newview/llaisapi.cpp` around lines 1693 - 1702, Extract the duplicated
sAISNotifyObserversPending coalescing logic into a shared static helper near the
existing AIS notification code, including posting the main-coroutine callback
and resetting the flag after gInventory.notifyObservers(). Replace both
backlog-path blocks around the relevant notification handling with calls to this
helper, preserving the current behavior.

1843-1848: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Guard the final deferred notification with the coalescing flag.

When the backlog path already posted a deferred notifyObservers() (flag is still true), this unconditional post queues a second notifyObservers() that will run after the backlog lambda. The second call iterates all observers but processes no changes (IDs already cleared). Checking !sAISNotifyObserversPending avoids the redundant post — the pending backlog lambda will process all accumulated changes since doUpdate() doesn't yield between the backlog post and this final post.

♻️ Proposed fix
-    LLAppViewer::instance()->postToMainCoro(
-        []()
-        {
-            gInventory.notifyObservers();
-        });
+    if (!sAISNotifyObserversPending)
+    {
+        LLAppViewer::instance()->postToMainCoro(
+            []()
+            {
+                gInventory.notifyObservers();
+            });
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@indra/newview/llaisapi.cpp` around lines 1843 - 1848, Guard the final
deferred notification in the surrounding AIS update flow with
!sAISNotifyObserversPending before calling
LLAppViewer::instance()->postToMainCoro. Keep the existing notifyObservers
callback unchanged, and avoid posting it when the backlog path has already
scheduled the pending notification.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@indra/newview/llaisapi.cpp`:
- Around line 1693-1702: Extract the duplicated sAISNotifyObserversPending
coalescing logic into a shared static helper near the existing AIS notification
code, including posting the main-coroutine callback and resetting the flag after
gInventory.notifyObservers(). Replace both backlog-path blocks around the
relevant notification handling with calls to this helper, preserving the current
behavior.
- Around line 1843-1848: Guard the final deferred notification in the
surrounding AIS update flow with !sAISNotifyObserversPending before calling
LLAppViewer::instance()->postToMainCoro. Keep the existing notifyObservers
callback unchanged, and avoid posting it when the backlog path has already
scheduled the pending notification.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: eb6fd5b0-2819-445c-be3c-8636fe17e72c

📥 Commits

Reviewing files that changed from the base of the PR and between bd86aed and aa6b43b.

📒 Files selected for processing (2)
  • indra/newview/llaisapi.cpp
  • indra/newview/llinventorymodel.cpp

Extract the duplicated sAISNotifyObserversPending coalescing logic from
the category and item creation backlog paths into a shared static helper
aisScheduleNotifyObservers(). Guard the final postToMainCoro at the end
of AISUpdate::doUpdate() with !sAISNotifyObserversPending to avoid posting
a redundant notifyObservers() when the backlog path has already scheduled
one.

No behaviour change.
Addresses review nitpicks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant