From e42ec63bfd7ada1087a00ca3ccc39c95679b7fab Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Fri, 23 Jan 2026 22:51:27 +0200 Subject: #5046 Fix a long freeze when fetching inventory --- indra/llcommon/lleventcoro.cpp | 12 ++++++++++++ indra/llcommon/lleventcoro.h | 5 +++++ indra/newview/llaisapi.cpp | 7 ++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index e1fc4764f6..bb2cd4fb2e 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -137,6 +137,18 @@ void llcoro::suspendUntilTimeout(float seconds) suspendUntilEventOnWithTimeout(bogus, seconds, timedout); } +void llcoro::suspendUntilNextFrame() +{ + LLCoros::checkStop(); + LLCoros::TempStatus st("waiting for next frame"); + + // Listen for the next event on the "mainloop" event pump. + // Once per frame we get mainloop.post(newFrame); + LLEventPumpOrPumpName mainloop_pump("mainloop"); + // Wait for the next event (the event data is ignored). + suspendUntilEventOn(mainloop_pump); +} + namespace { diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 492563bb98..25a8a98e36 100644 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -84,6 +84,11 @@ void suspend(); */ void suspendUntilTimeout(float seconds); +/** + * Yield control from a coroutine until the next mainloop's newFrame event. + */ +void suspendUntilNextFrame(); + /** * Post specified LLSD event on the specified LLEventPump, then suspend for a * response on specified other LLEventPump. This is more than mere diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 1da1647fe8..9c76f56ef3 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -1060,7 +1060,12 @@ void AISUpdate::checkTimeout() { if (mTimer.hasExpired()) { - llcoro::suspend(); + // If we are taking too long, don't starve other tasks, + // yield to mainloop. + // If we use normal suspend(), there will be a chance of + // waking up from other suspends, before main coro had + // a chance, so wait for a frame tick instead. + llcoro::suspendUntilNextFrame(); LLCoros::checkStop(); mTimer.setTimerExpirySec(AIS_EXPIRY_SECONDS); } -- cgit v1.3