From eb9d34f65e64e35f01ae1c4198d2c5f5d16b8dfd Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 29 May 2012 01:06:07 +0200 Subject: [PATCH] FIRE-4702; Prevent crash due to race condition of llfolderciew being destroyed while still used in a callback. --- indra/newview/llfolderview.cpp | 30 +++++++++++++++++++++++++++++- indra/newview/llfolderview.h | 16 ++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index e7a4c4c31b..f76f2ff940 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -282,11 +282,18 @@ LLFolderView::LLFolderView(const Params& p) mPopupMenuHandle = menu->getHandle(); mListener->openItem(); + + mFolderviewProxy = 0; // FIRE-4702; } // Destroys the object LLFolderView::~LLFolderView( void ) { + // FIRE-4702; + if( mFolderviewProxy ) + mFolderviewProxy->mFolderview = 0; + // + closeRenamer(); // The release focus call can potentially call the @@ -995,7 +1002,15 @@ void LLFolderView::removeSelectedItems( void ) if (mSelectedItems.empty()) return; LLSD args; args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" : "DeleteItem"); - LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2)); + + // FIRE-4702; + + // LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2)); + + mFolderviewProxy = new FolderviewProxy(); + mFolderviewProxy->mFolderview = this; + LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&FolderviewProxy::onItemsRemovalConfirmation, mFolderviewProxy, _1, _2)); + // } bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector& selectedItems) @@ -2647,3 +2662,16 @@ void properties_selected_items(void* user_data) fv->propertiesSelectedItems(); } } + +// FIRE-4702; +void LLFolderView::FolderviewProxy::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response) +{ + if( mFolderview ) + { + mFolderview->mFolderviewProxy = 0; + mFolderview->onItemsRemovalConfirmation( notification, response); + } + delete this; +} +// + diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 24c2412f76..f84c36793e 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -341,6 +341,22 @@ public: static F32 sAutoOpenTime; LLTextBox* mStatusTextBox; + + // FIRE-4702; When displaying a confirmation dialog to delete items, don't pass + // this, but instead a new proxy objects. this can be destroyed if there is a + // race condition between displaying the confirmation dialog and this folderview + // being populated at the same time. +private: + struct FolderviewProxy + { + void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response); + LLFolderView *mFolderview; + }; + + friend struct FolderviewProxy; + + FolderviewProxy *mFolderviewProxy; + // }; bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);