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 | |
| parent | cfad42bea9baa7390eed7422fca12e8c00833837 (diff) | |
#3379 Crash on gIdleCallbacks iteration
Diffstat (limited to 'indra')
| -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();          } | 
