From 5478f2a223b5b679fe4515aa5a88f9ae1ed36985 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 11 Jul 2017 14:54:29 +0300
Subject: MAINT-7581 [contribution] Closing the 'Replace links' floater crashes
 the viewer if a replace is in progress

---
 doc/contributions.txt                  |  1 +
 indra/newview/llfloaterlinkreplace.cpp | 22 +++++++++-------------
 indra/newview/llfloaterlinkreplace.h   | 11 +++--------
 3 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 549adaaef7..064639fe72 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -823,6 +823,7 @@ Kitty Barnett
 	MAINT-6154
 	MAINT-6568
 	STORM-2149
+	MAINT-7581
 Kolor Fall
 Komiko Okamoto
 Korvel Noh
diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp
index 3f80d6f1a4..10cce3bd22 100644
--- a/indra/newview/llfloaterlinkreplace.cpp
+++ b/indra/newview/llfloaterlinkreplace.cpp
@@ -41,16 +41,13 @@ LLFloaterLinkReplace::LLFloaterLinkReplace(const LLSD& key)
 	mRemainingItems(0),
 	mSourceUUID(LLUUID::null),
 	mTargetUUID(LLUUID::null),
-	mInstance(NULL),
 	mBatchSize(gSavedSettings.getU32("LinkReplaceBatchSize"))
 {
 	mEventTimer.stop();
-	mInstance = this;
 }
 
 LLFloaterLinkReplace::~LLFloaterLinkReplace()
 {
-	mInstance = NULL;
 }
 
 BOOL LLFloaterLinkReplace::postBuild()
@@ -180,11 +177,9 @@ void LLFloaterLinkReplace::onStartClicked()
 	}
 }
 
-void LLFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id,
-												const LLUUID& target_item_id,
-												bool needs_wearable_ordering_update,
-												bool needs_description_update,
-												const LLUUID& outfit_folder_id)
+// static
+void LLFloaterLinkReplace::linkCreatedCallback(LLHandle<LLFloaterLinkReplace> floater_handle, const LLUUID& old_item_id, const LLUUID& target_item_id,
+												bool needs_wearable_ordering_update, bool needs_description_update, const LLUUID& outfit_folder_id)
 {
 	LL_DEBUGS() << "Inventory link replace:" << LL_NEWLINE
 		<< " - old_item_id = " << old_item_id.asString() << LL_NEWLINE
@@ -239,20 +234,21 @@ void LLFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id,
 		outfit_update_folder = outfit_folder_id;
 	}
 
-	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::itemRemovedCallback, this, outfit_update_folder));
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::itemRemovedCallback, floater_handle, outfit_update_folder));
 	remove_inventory_object(old_item_id, cb);
 }
 
-void LLFloaterLinkReplace::itemRemovedCallback(const LLUUID& outfit_folder_id)
+// static
+void LLFloaterLinkReplace::itemRemovedCallback(LLHandle<LLFloaterLinkReplace> floater_handle, const LLUUID& outfit_folder_id)
 {
 	if (outfit_folder_id.notNull())
 	{
 		LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(outfit_folder_id);
 	}
 
-	if (mInstance)
+	if (!floater_handle.isDead())
 	{
-		decreaseOpenItemCount();
+		floater_handle.get()->decreaseOpenItemCount();
 	}
 }
 
@@ -324,7 +320,7 @@ void LLFloaterLinkReplace::processBatch(LLInventoryModel::item_array_t items)
 			LLInventoryObject::const_object_list_t obj_array;
 			obj_array.push_back(LLConstPointer<LLInventoryObject>(target_item));
 			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::linkCreatedCallback,
-																											this,
+																											getDerivedHandle<LLFloaterLinkReplace>(),
 																											source_item->getUUID(),
 																											target_item->getUUID(),
 																											needs_wearable_ordering_update,
diff --git a/indra/newview/llfloaterlinkreplace.h b/indra/newview/llfloaterlinkreplace.h
index 377dd1d450..dd5c301206 100644
--- a/indra/newview/llfloaterlinkreplace.h
+++ b/indra/newview/llfloaterlinkreplace.h
@@ -98,12 +98,9 @@ private:
 	void updateFoundLinks();
 	void processBatch(LLInventoryModel::item_array_t items);
 
-	void linkCreatedCallback(const LLUUID& old_item_id,
-								const LLUUID& target_item_id,
-								bool needs_wearable_ordering_update,
-								bool needs_description_update,
-								const LLUUID& outfit_folder_id);
-	void itemRemovedCallback(const LLUUID& outfit_folder_id);
+	static void linkCreatedCallback(LLHandle<LLFloaterLinkReplace> floater_handle, const LLUUID& old_item_id, const LLUUID& target_item_id,
+	                                bool needs_wearable_ordering_update, bool needs_description_update, const LLUUID& outfit_folder_id);
+	static void itemRemovedCallback(LLHandle<LLFloaterLinkReplace> floater_handle, const LLUUID& outfit_folder_id);
 
 	void onSourceItemDrop(const LLUUID& source_item_id);
 	void onTargetItemDrop(const LLUUID& target_item_id);
@@ -120,8 +117,6 @@ private:
 	U32		mBatchSize;
 
 	LLInventoryModel::item_array_t	mRemainingInventoryItems;
-
-	LLFloaterLinkReplace* mInstance;
 };
 
 #endif // LL_FLOATERLINKREPLACE_H
-- 
cgit v1.2.3