From 281c3d8beec393de9afced57c6756d0d367a1c77 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 Nov 2020 21:40:54 +0200 Subject: SL-14270 Crash accessing deleted 'parent' via callback from child --- indra/llui/llfolderviewmodel.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llui/llfolderviewmodel.h') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index f71a88c56e..903049b9af 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -248,6 +248,8 @@ public: mChildren.clear(); } + virtual ~LLFolderViewModelItemCommon(); + void requestSort() { mSortVersion = -1; } S32 getSortVersion() { return mSortVersion; } void setSortVersion(S32 version) { mSortVersion = version;} @@ -399,6 +401,8 @@ public: mFolderView(NULL) {} + virtual ~LLFolderViewModelCommon() {} + virtual void requestSortAll() { // sort everything -- cgit v1.2.3 From d17af5f3a6303c816f357b1e94a28cae36828b69 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 Nov 2020 21:58:12 +0200 Subject: SL-14270 A bit of cleanup #1 --- indra/llui/llfolderviewmodel.h | 130 ++++------------------------------------- 1 file changed, 12 insertions(+), 118 deletions(-) (limited to 'indra/llui/llfolderviewmodel.h') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 903049b9af..d8e5bccc9b 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -231,23 +231,7 @@ protected: class LLFolderViewModelItemCommon : public LLFolderViewModelItem { public: - LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model) - : mSortVersion(-1), - mPassedFilter(true), - mPassedFolderFilter(true), - mStringMatchOffsetFilter(std::string::npos), - mStringFilterSize(0), - mFolderViewItem(NULL), - mLastFilterGeneration(-1), - mLastFolderFilterGeneration(-1), - mMarkedDirtyGeneration(-1), - mMostFilteredDescendantGeneration(-1), - mParent(NULL), - mRootViewModel(root_view_model) - { - mChildren.clear(); - } - + LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model); virtual ~LLFolderViewModelItemCommon(); void requestSort() { mSortVersion = -1; } @@ -257,115 +241,28 @@ public: S32 getLastFilterGeneration() const { return mLastFilterGeneration; } S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; } S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; } - void dirtyFilter() - { - if(mMarkedDirtyGeneration < 0) - { - mMarkedDirtyGeneration = mLastFilterGeneration; - } - mLastFilterGeneration = -1; - mLastFolderFilterGeneration = -1; - - // bubble up dirty flag all the way to root - if (mParent) - { - mParent->dirtyFilter(); - } - } - void dirtyDescendantsFilter() - { - mMostFilteredDescendantGeneration = -1; - if (mParent) - { - mParent->dirtyDescendantsFilter(); - } - } + void dirtyFilter(); + void dirtyDescendantsFilter(); bool hasFilterStringMatch(); std::string::size_type getFilterStringOffset(); std::string::size_type getFilterStringSize(); typedef std::list child_list_t; - virtual void addChild(LLFolderViewModelItem* child) - { - // Avoid duplicates: bail out if that child is already present in the list - // Note: this happens when models are created before views - child_list_t::const_iterator iter; - for (iter = mChildren.begin(); iter != mChildren.end(); iter++) - { - if (child == *iter) - { - return; - } - } - mChildren.push_back(child); - child->setParent(this); - dirtyFilter(); - requestSort(); - } - virtual void removeChild(LLFolderViewModelItem* child) - { - mChildren.remove(child); - child->setParent(NULL); - dirtyDescendantsFilter(); - dirtyFilter(); - } + virtual void addChild(LLFolderViewModelItem* child); + virtual void removeChild(LLFolderViewModelItem* child); - virtual void clearChildren() - { - // As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects - // This is different and not equivalent to calling removeChild() on each child - std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); - mChildren.clear(); - dirtyDescendantsFilter(); - dirtyFilter(); - } + virtual void clearChildren(); child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); } child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); } child_list_t::size_type getChildrenCount() const { return mChildren.size(); } - void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) - { - mPassedFilter = passed; - mLastFilterGeneration = filter_generation; - mStringMatchOffsetFilter = string_offset; - mStringFilterSize = string_size; - mMarkedDirtyGeneration = -1; - } - - void setPassedFolderFilter(bool passed, S32 filter_generation) - { - mPassedFolderFilter = passed; - mLastFolderFilterGeneration = filter_generation; - } - - virtual bool potentiallyVisible() - { - return passedFilter() // we've passed the filter - || (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet - || descendantsPassedFilter(); - } - - virtual bool passedFilter(S32 filter_generation = -1) - { - if (filter_generation < 0) - { - filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration(); - } - bool passed_folder_filter = mPassedFolderFilter && (mLastFolderFilterGeneration >= filter_generation); - bool passed_filter = mPassedFilter && (mLastFilterGeneration >= filter_generation); - return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation)); - } - - virtual bool descendantsPassedFilter(S32 filter_generation = -1) - { - if (filter_generation < 0) - { - filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration(); - } - return mMostFilteredDescendantGeneration >= filter_generation; - } + void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0); + void setPassedFolderFilter(bool passed, S32 filter_generation); + virtual bool potentiallyVisible(); + virtual bool passedFilter(S32 filter_generation = -1); + virtual bool descendantsPassedFilter(S32 filter_generation = -1); protected: @@ -396,10 +293,7 @@ protected: class LLFolderViewModelCommon : public LLFolderViewModelInterface { public: - LLFolderViewModelCommon() - : mTargetSortVersion(0), - mFolderView(NULL) - {} + LLFolderViewModelCommon(); virtual ~LLFolderViewModelCommon() {} -- cgit v1.2.3 From dc136e8dc886cf4798804757d3002f5711995b97 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 Nov 2020 22:54:28 +0200 Subject: SL-14270 A bit of cleanup #2 --- indra/llui/llfolderviewmodel.h | 65 +++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 35 deletions(-) (limited to 'indra/llui/llfolderviewmodel.h') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index d8e5bccc9b..ba8733c86d 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -38,7 +38,6 @@ enum EInventorySortGroup SG_ITEM }; -class LLFontGL; class LLInventoryModel; class LLMenuGL; class LLUIImage; @@ -232,25 +231,25 @@ class LLFolderViewModelItemCommon : public LLFolderViewModelItem { public: LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model); - virtual ~LLFolderViewModelItemCommon(); + virtual ~LLFolderViewModelItemCommon() override; - void requestSort() { mSortVersion = -1; } - S32 getSortVersion() { return mSortVersion; } - void setSortVersion(S32 version) { mSortVersion = version;} + void requestSort() override { mSortVersion = -1; } + S32 getSortVersion() override { return mSortVersion; } + void setSortVersion(S32 version) override { mSortVersion = version;} - S32 getLastFilterGeneration() const { return mLastFilterGeneration; } + S32 getLastFilterGeneration() const override { return mLastFilterGeneration; } S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; } - S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; } - void dirtyFilter(); - void dirtyDescendantsFilter(); - bool hasFilterStringMatch(); - std::string::size_type getFilterStringOffset(); - std::string::size_type getFilterStringSize(); + S32 getMarkedDirtyGeneration() const override { return mMarkedDirtyGeneration; } + void dirtyFilter() override; + void dirtyDescendantsFilter() override; + bool hasFilterStringMatch() override; + std::string::size_type getFilterStringOffset() override; + std::string::size_type getFilterStringSize() override; typedef std::list child_list_t; - virtual void addChild(LLFolderViewModelItem* child); - virtual void removeChild(LLFolderViewModelItem* child); + virtual void addChild(LLFolderViewModelItem* child) override; + virtual void removeChild(LLFolderViewModelItem* child) override; virtual void clearChildren(); @@ -258,16 +257,16 @@ public: child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); } child_list_t::size_type getChildrenCount() const { return mChildren.size(); } - void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0); - void setPassedFolderFilter(bool passed, S32 filter_generation); - virtual bool potentiallyVisible(); - virtual bool passedFilter(S32 filter_generation = -1); - virtual bool descendantsPassedFilter(S32 filter_generation = -1); + void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) override; + void setPassedFolderFilter(bool passed, S32 filter_generation) override; + virtual bool potentiallyVisible() override; + virtual bool passedFilter(S32 filter_generation = -1) override; + virtual bool descendantsPassedFilter(S32 filter_generation = -1) override; protected: - virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; } - virtual bool hasParent() { return mParent != NULL; } + virtual void setParent(LLFolderViewModelItem* parent) override { mParent = parent; } + virtual bool hasParent() override { return mParent != NULL; } S32 mSortVersion; bool mPassedFilter; @@ -284,7 +283,7 @@ protected: LLFolderViewModelItem* mParent; LLFolderViewModelInterface& mRootViewModel; - void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;} + void setFolderViewItem(LLFolderViewItem* folder_view_item) override { mFolderViewItem = folder_view_item;} LLFolderViewItem* mFolderViewItem; }; @@ -295,17 +294,13 @@ class LLFolderViewModelCommon : public LLFolderViewModelInterface public: LLFolderViewModelCommon(); - virtual ~LLFolderViewModelCommon() {} + virtual ~LLFolderViewModelCommon() override {} - virtual void requestSortAll() - { - // sort everything - mTargetSortVersion++; - } - virtual std::string getStatusText(); - virtual void filter(); + virtual void requestSortAll() override; + virtual std::string getStatusText() override; + virtual void filter() override; - void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;} + void setFolderView(LLFolderView* folder_view) override { mFolderView = folder_view;} protected: bool needsSort(class LLFolderViewModelItem* item); @@ -329,7 +324,7 @@ public: mFilter(filter) {} - virtual ~LLFolderViewModel() + virtual ~LLFolderViewModel() override { delete mSorter; mSorter = NULL; @@ -347,8 +342,8 @@ public: // By default, we assume the content is available. If a network fetch mechanism is implemented for the model, // this method needs to be overloaded and return the relevant fetch status. - virtual bool contentsReady() { return true; } - virtual bool isFolderComplete(LLFolderViewFolder* folder) { return true; } + virtual bool contentsReady() override { return true; } + virtual bool isFolderComplete(LLFolderViewFolder* folder) override { return true; } struct ViewModelCompare { @@ -369,7 +364,7 @@ public: const SortType& mSorter; }; - void sort(LLFolderViewFolder* folder) + void sort(LLFolderViewFolder* folder) override { if (needsSort(folder->getViewModelItem())) { -- cgit v1.2.3 From e1ae2e7cbd8335abf5463fe28aa942d46523638e Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 12 Nov 2020 00:06:39 +0200 Subject: Mac buildfix --- indra/llui/llfolderviewmodel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui/llfolderviewmodel.h') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index ba8733c86d..6e739a57a6 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -336,8 +336,8 @@ public: virtual const SortType& getSorter() const { return *mSorter; } virtual void setSorter(const SortType& sorter) { mSorter = new SortType(sorter); requestSortAll(); } - virtual FilterType& getFilter() { return *mFilter; } - virtual const FilterType& getFilter() const { return *mFilter; } + virtual FilterType& getFilter() override { return *mFilter; } + virtual const FilterType& getFilter() const override { return *mFilter; } virtual void setFilter(const FilterType& filter) { mFilter = new FilterType(filter); } // By default, we assume the content is available. If a network fetch mechanism is implemented for the model, -- cgit v1.2.3 From 7ab3de94cd10cb6aa9d1f4a6607366edae101464 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 7 Dec 2020 19:29:39 +0200 Subject: Revert "SL-14270 Crash accessing deleted 'parent' via callback from child" There are random inventory's buildViewsTree crashes in branch with SL-14270 commit and there doesn't seem to be anything else inventory related that could have caused those. Reverting commits to see if it fixes crashes. --- indra/llui/llfolderviewmodel.h | 169 ++++++++++++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 36 deletions(-) (limited to 'indra/llui/llfolderviewmodel.h') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 6e739a57a6..f4ddfa8f18 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -38,6 +38,7 @@ enum EInventorySortGroup SG_ITEM }; +class LLFontGL; class LLInventoryModel; class LLMenuGL; class LLUIImage; @@ -230,43 +231,134 @@ protected: class LLFolderViewModelItemCommon : public LLFolderViewModelItem { public: - LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model); - virtual ~LLFolderViewModelItemCommon() override; + LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model) + : mSortVersion(-1), + mPassedFilter(true), + mPassedFolderFilter(true), + mStringMatchOffsetFilter(std::string::npos), + mStringFilterSize(0), + mFolderViewItem(NULL), + mLastFilterGeneration(-1), + mLastFolderFilterGeneration(-1), + mMarkedDirtyGeneration(-1), + mMostFilteredDescendantGeneration(-1), + mParent(NULL), + mRootViewModel(root_view_model) + { + mChildren.clear(); + } - void requestSort() override { mSortVersion = -1; } - S32 getSortVersion() override { return mSortVersion; } - void setSortVersion(S32 version) override { mSortVersion = version;} + void requestSort() { mSortVersion = -1; } + S32 getSortVersion() { return mSortVersion; } + void setSortVersion(S32 version) { mSortVersion = version;} - S32 getLastFilterGeneration() const override { return mLastFilterGeneration; } + S32 getLastFilterGeneration() const { return mLastFilterGeneration; } S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; } - S32 getMarkedDirtyGeneration() const override { return mMarkedDirtyGeneration; } - void dirtyFilter() override; - void dirtyDescendantsFilter() override; - bool hasFilterStringMatch() override; - std::string::size_type getFilterStringOffset() override; - std::string::size_type getFilterStringSize() override; + S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; } + void dirtyFilter() + { + if(mMarkedDirtyGeneration < 0) + { + mMarkedDirtyGeneration = mLastFilterGeneration; + } + mLastFilterGeneration = -1; + mLastFolderFilterGeneration = -1; + + // bubble up dirty flag all the way to root + if (mParent) + { + mParent->dirtyFilter(); + } + } + void dirtyDescendantsFilter() + { + mMostFilteredDescendantGeneration = -1; + if (mParent) + { + mParent->dirtyDescendantsFilter(); + } + } + bool hasFilterStringMatch(); + std::string::size_type getFilterStringOffset(); + std::string::size_type getFilterStringSize(); typedef std::list child_list_t; - virtual void addChild(LLFolderViewModelItem* child) override; - virtual void removeChild(LLFolderViewModelItem* child) override; + virtual void addChild(LLFolderViewModelItem* child) + { + mChildren.push_back(child); + child->setParent(this); + dirtyFilter(); + requestSort(); + } + virtual void removeChild(LLFolderViewModelItem* child) + { + mChildren.remove(child); + child->setParent(NULL); + dirtyDescendantsFilter(); + dirtyFilter(); + } - virtual void clearChildren(); + virtual void clearChildren() + { + // As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects + // This is different and not equivalent to calling removeChild() on each child + std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); + mChildren.clear(); + dirtyDescendantsFilter(); + dirtyFilter(); + } child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); } child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); } child_list_t::size_type getChildrenCount() const { return mChildren.size(); } - void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) override; - void setPassedFolderFilter(bool passed, S32 filter_generation) override; - virtual bool potentiallyVisible() override; - virtual bool passedFilter(S32 filter_generation = -1) override; - virtual bool descendantsPassedFilter(S32 filter_generation = -1) override; + void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) + { + mPassedFilter = passed; + mLastFilterGeneration = filter_generation; + mStringMatchOffsetFilter = string_offset; + mStringFilterSize = string_size; + mMarkedDirtyGeneration = -1; + } + + void setPassedFolderFilter(bool passed, S32 filter_generation) + { + mPassedFolderFilter = passed; + mLastFolderFilterGeneration = filter_generation; + } + + virtual bool potentiallyVisible() + { + return passedFilter() // we've passed the filter + || (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet + || descendantsPassedFilter(); + } + + virtual bool passedFilter(S32 filter_generation = -1) + { + if (filter_generation < 0) + { + filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration(); + } + bool passed_folder_filter = mPassedFolderFilter && (mLastFolderFilterGeneration >= filter_generation); + bool passed_filter = mPassedFilter && (mLastFilterGeneration >= filter_generation); + return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation)); + } + + virtual bool descendantsPassedFilter(S32 filter_generation = -1) + { + if (filter_generation < 0) + { + filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration(); + } + return mMostFilteredDescendantGeneration >= filter_generation; + } protected: - virtual void setParent(LLFolderViewModelItem* parent) override { mParent = parent; } - virtual bool hasParent() override { return mParent != NULL; } + virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; } + virtual bool hasParent() { return mParent != NULL; } S32 mSortVersion; bool mPassedFilter; @@ -283,7 +375,7 @@ protected: LLFolderViewModelItem* mParent; LLFolderViewModelInterface& mRootViewModel; - void setFolderViewItem(LLFolderViewItem* folder_view_item) override { mFolderViewItem = folder_view_item;} + void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;} LLFolderViewItem* mFolderViewItem; }; @@ -292,15 +384,20 @@ protected: class LLFolderViewModelCommon : public LLFolderViewModelInterface { public: - LLFolderViewModelCommon(); - - virtual ~LLFolderViewModelCommon() override {} + LLFolderViewModelCommon() + : mTargetSortVersion(0), + mFolderView(NULL) + {} - virtual void requestSortAll() override; - virtual std::string getStatusText() override; - virtual void filter() override; + virtual void requestSortAll() + { + // sort everything + mTargetSortVersion++; + } + virtual std::string getStatusText(); + virtual void filter(); - void setFolderView(LLFolderView* folder_view) override { mFolderView = folder_view;} + void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;} protected: bool needsSort(class LLFolderViewModelItem* item); @@ -324,7 +421,7 @@ public: mFilter(filter) {} - virtual ~LLFolderViewModel() override + virtual ~LLFolderViewModel() { delete mSorter; mSorter = NULL; @@ -336,14 +433,14 @@ public: virtual const SortType& getSorter() const { return *mSorter; } virtual void setSorter(const SortType& sorter) { mSorter = new SortType(sorter); requestSortAll(); } - virtual FilterType& getFilter() override { return *mFilter; } - virtual const FilterType& getFilter() const override { return *mFilter; } + virtual FilterType& getFilter() { return *mFilter; } + virtual const FilterType& getFilter() const { return *mFilter; } virtual void setFilter(const FilterType& filter) { mFilter = new FilterType(filter); } // By default, we assume the content is available. If a network fetch mechanism is implemented for the model, // this method needs to be overloaded and return the relevant fetch status. - virtual bool contentsReady() override { return true; } - virtual bool isFolderComplete(LLFolderViewFolder* folder) override { return true; } + virtual bool contentsReady() { return true; } + virtual bool isFolderComplete(LLFolderViewFolder* folder) { return true; } struct ViewModelCompare { @@ -364,7 +461,7 @@ public: const SortType& mSorter; }; - void sort(LLFolderViewFolder* folder) override + void sort(LLFolderViewFolder* folder) { if (needsSort(folder->getViewModelItem())) { -- cgit v1.2.3