diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2026-08-12 18:52:57 +0300 |
|---|---|---|
| committer | Andrey Lihatskiy <118752495+marchcat@users.noreply.github.com> | 2026-08-12 20:15:39 +0300 |
| commit | 21bb60fc65e7fa6c3cf472a29cda220f653af1d8 (patch) | |
| tree | 5be94310d9a9f25ac80cc2227638b224d079b71d | |
| parent | f6fa702706aeba8c5a3760a98883943cba3c973b (diff) | |
#6117 Guard against stale nearby chat toast handles
| -rw-r--r-- | indra/newview/llfloaterimnearbychathandler.cpp | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 3f1fe50b73..e92672f684 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -145,6 +145,8 @@ protected: void updateToastFadingTime(); + LLToast* getToastFromPool(); + create_toast_panel_callback_t m_create_toast_panel_callback_t; bool createPoolToast(); @@ -238,9 +240,19 @@ void LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime() S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime"); toast_list_t::iterator it; - for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it) + for(it = m_toast_pool.begin(); it != m_toast_pool.end();) { - (*it).get()->setLifetime(seconds); + LLToast* toast = it->get(); + if (toast) + { + toast->setLifetime(seconds); + ++it; + } + else + { + LL_WARNS("NearbyChat") << "Discarding destroyed toast from pool" << LL_ENDL; + it = m_toast_pool.erase(it); + } } } @@ -249,12 +261,38 @@ void LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime() S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime"); toast_list_t::iterator it; - for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it) + for(it = m_toast_pool.begin(); it != m_toast_pool.end();) { - (*it).get()->setFadingTime(seconds); + LLToast* toast = it->get(); + if (toast) + { + toast->setFadingTime(seconds); + ++it; + } + else + { + LL_WARNS("NearbyChat") << "Discarding destroyed toast from pool" << LL_ENDL; + it = m_toast_pool.erase(it); + } } } +LLToast* LLFloaterIMNearbyChatScreenChannel::getToastFromPool() +{ + while (!m_toast_pool.empty()) + { + LLToast* toast = m_toast_pool.back().get(); + m_toast_pool.pop_back(); + + if (toast) + return toast; + + LL_WARNS("NearbyChat") << "Discarding destroyed toast from pool" << LL_ENDL; + } + + return nullptr; +} + bool LLFloaterIMNearbyChatScreenChannel::createPoolToast() { LLFloaterIMNearbyChatToastPanel* panel= m_create_toast_panel_callback_t(); @@ -344,9 +382,18 @@ void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat) //take 1st element from pool, (re)initialize it, put it in active toasts LL_DEBUGS("NearbyChat") << "Getting toast from pool" << LL_ENDL; - LLToast* toast = m_toast_pool.back().get(); + LLToast* toast = getToastFromPool(); + if (!toast) + { + // A toast can be destroyed while its handle remains in the pool. + // Replenish the pool instead of dereferencing the dead handle. + if (!createPoolToast()) + return; - m_toast_pool.pop_back(); + toast = getToastFromPool(); + if (!toast) + return; + } LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel()); |
