summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-04-12 10:16:34 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-04-12 10:16:42 +0300
commit1dacabe780cba99015203e98cc0c66fbcb660c80 (patch)
tree2a24b9ed4176df7d967c5de11dd166efb9acfbd9 /indra/llui
parentcfad42bea9baa7390eed7422fca12e8c00833837 (diff)
#3379 Crash on gIdleCallbacks iteration
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llfolderviewitem.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index c39613b1b5..87eee6a9ae 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1866,7 +1866,7 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data);
if (self->mFavoritesDirtyFlags == 0)
{
- LL_WARNS() << "Called onIdleUpdateFavorites without dirty flags set" << LL_ENDL;
+ // already processed either on previous run or by a different callback
gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
return;
}
@@ -1892,12 +1892,20 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
parent->setHasFavorites(true);
if (parent->mFavoritesDirtyFlags)
{
- gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, parent);
+ // Parent will remove onIdleUpdateFavorites later, don't remove now,
+ // We are inside gIdleCallbacks. Removing 'self' callback is safe,
+ // but removing 'parent' can invalidate following iterator
parent->mFavoritesDirtyFlags = 0;
}
parent = parent->getParentFolder();
}
}
+ else
+ {
+ LL_WARNS() << "FAVORITE_ADDED for a folder without favorites" << LL_ENDL;
+ self->mFavoritesDirtyFlags = 0;
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
+ }
}
else if (self->mFavoritesDirtyFlags > FAVORITE_ADDED)
{
@@ -1950,7 +1958,9 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
parent->setHasFavorites(true);
if (parent->mFavoritesDirtyFlags)
{
- gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, parent);
+ // Parent will remove onIdleUpdateFavorites later, don't remove now,
+ // We are inside gIdleCallbacks. Removing 'self' callback is safe,
+ // but removing 'parent' can invalidate following iterator
parent->mFavoritesDirtyFlags = 0;
}
parent = parent->getParentFolder();
@@ -1959,8 +1969,10 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
}
if (parent->mFavoritesDirtyFlags)
{
+ // Parent will remove onIdleUpdateFavorites later, don't remove now.
+ // We are inside gIdleCallbacks. Removing 'self' callback is safe,
+ // but removing 'parent' can invalidate following iterator
parent->mFavoritesDirtyFlags = 0;
- gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, parent);
}
parent = parent->getParentFolder();
}