diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-04-12 10:16:34 +0300 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-04-12 10:16:42 +0300 |
commit | 1dacabe780cba99015203e98cc0c66fbcb660c80 (patch) | |
tree | 2a24b9ed4176df7d967c5de11dd166efb9acfbd9 /indra/llui | |
parent | cfad42bea9baa7390eed7422fca12e8c00833837 (diff) |
#3379 Crash on gIdleCallbacks iteration
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llfolderviewitem.cpp | 20 |
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(); } |