From b86a3e39cf8d0d17d5cd30743a871e3078331077 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Mon, 17 Dec 2012 13:24:57 -0500
Subject: SH-3604 FIX - resolved an issue with simulated failures/retry logic

---
 indra/newview/llappearancemgr.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index f957aadec5..7fd7b33be4 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -217,12 +217,12 @@ public:
 		if (ll_frand()<gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
 		{
 			// simulate server failure by not sending the request.
-			return;
+			// do nothing
+			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << " linked_id " << linked_id << llendl;
 		}
-		
-		if (!requestOperation(linked_id))
+		else if (!requestOperation(linked_id))
 		{
-			LL_DEBUGS("Avatar") << "item_id " << item_id << " linked_id " << linked_id << " not requested" << llendl;
+			LL_DEBUGS("Avatar") << "item_id " << item_id << " linked_id " << linked_id << " requestOperation false, skipping" << llendl;
 			return;
 		}
 
@@ -237,7 +237,6 @@ public:
 		{
 			mRetryCounts[linked_id]++;
 		}
-
 	}
 
 	virtual bool requestOperation(const LLUUID& item_id) = 0;
-- 
cgit v1.2.3


From fb99b1a1b4c40932af1e3fbe4b3e371a87ad4c8f Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Mon, 17 Dec 2012 16:51:25 -0500
Subject: SH-3629 WIP - fixed out-of-order outfit items

---
 indra/newview/llappearancemgr.cpp | 32 +++++++++-----------------------
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 7fd7b33be4..7751da7b41 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -198,44 +198,30 @@ public:
 	// Request or re-request operation for specified item.
 	void addItem(const LLUUID& item_id)
 	{
-		LLUUID linked_id;
-		if (gInventory.getItem(item_id))
-		{
-			linked_id = gInventory.getItem(item_id)->getLinkedUUID();
-		}
-		else if (gInventory.getCategory(item_id))
-		{
-			linked_id = item_id;
-		}
-		else
-		{
-			llwarns << "no referent found for item_id " << item_id << llendl;
-			return;
-		}
-		LL_DEBUGS("Avatar") << "item_id " << item_id << " -> linked_id " << linked_id << llendl;
+		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl;
 		
 		if (ll_frand()<gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
 		{
 			// simulate server failure by not sending the request.
 			// do nothing
-			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << " linked_id " << linked_id << llendl;
+			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
 		}
-		else if (!requestOperation(linked_id))
+		else if (!requestOperation(item_id))
 		{
-			LL_DEBUGS("Avatar") << "item_id " << item_id << " linked_id " << linked_id << " requestOperation false, skipping" << llendl;
+			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;
 			return;
 		}
 
 		mPendingRequests++;
 		// On a re-request, this will reset the timer.
-		mWaitTimes[linked_id] = LLTimer();
-		if (mRetryCounts.find(linked_id) == mRetryCounts.end())
+		mWaitTimes[item_id] = LLTimer();
+		if (mRetryCounts.find(item_id) == mRetryCounts.end())
 		{
-			mRetryCounts[linked_id] = 0;
+			mRetryCounts[item_id] = 0;
 		}
 		else
 		{
-			mRetryCounts[linked_id]++;
+			mRetryCounts[item_id]++;
 		}
 	}
 
@@ -435,7 +421,7 @@ public:
 			LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
 			// create an inventory item link.
 			link_inventory_item(gAgent.getID(),
-								item_id,
+								item->getLinkedUUID(),
 								mDstCatID,
 								item->getName(),
 								item->LLInventoryItem::getDescription(),
-- 
cgit v1.2.3


From 42496cd672436cc4d32f5546fd04294931b8f0b6 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Mon, 17 Dec 2012 18:34:13 -0500
Subject: SH-3629 WIP - avoid clobbering links to desired items that are
 already in the COF, as will be the case when wearing an outfit with required
 body parts missing

---
 indra/newview/llappearancemgr.cpp | 49 ++++++++++++++++++++-------------------
 indra/newview/llappearancemgr.h   |  3 +--
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 7751da7b41..1044732f4b 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -418,6 +418,11 @@ public:
 		LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item)
 		{
+			if (item->getParentUUID() == mDstCatID)
+			{
+				LL_DEBUGS("Avatar") << "item " << item_id << " name " << item->getName() << " is already a child of " << mDstCatID << llendl;
+				return false;
+			}
 			LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
 			// create an inventory item link.
 			link_inventory_item(gAgent.getID(),
@@ -436,7 +441,7 @@ public:
 			LLViewerInventoryCategory *catp = gInventory.getCategory(item_id);
 			if (!catp)
 			{
-				llwarns << "id not found as inventory item or category " << item_id << llendl;
+				llwarns << "link request failed, id not found as inventory item or category " << item_id << llendl;
 				return false;
 			}
 			const LLUUID cof = LLAppearanceMgr::instance().getCOF();
@@ -1621,7 +1626,7 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
 	}
 }
 
-void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links)
+void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items)
 {
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
@@ -1634,7 +1639,14 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin
 			continue;
 		if (item->getIsLinkType())
 		{
-			gInventory.purgeObject(item->getUUID());
+			if (keep_items && keep_items->find(item) != LLInventoryModel::item_array_t::FAIL)
+			{
+				llinfos << "preserved item" << llendl;
+			}
+			else
+			{
+				gInventory.purgeObject(item->getUUID());
+			}
 		}
 	}
 }
@@ -1746,34 +1758,23 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
 	getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE, false);
 	removeDuplicateItems(gest_items);
 	
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
-#endif
-
 	// Create links to new COF contents.
 	LL_DEBUGS("Avatar") << self_av_string() << "creating LLCallAfterInventoryLinkMgr" << LL_ENDL;
+
+	LLInventoryModel::item_array_t all_items;
+	all_items += body_items;
+	all_items += wear_items;
+	all_items += obj_items;
+	all_items += gest_items;
+
+	// Will link all the above items.
 	bool update_base_outfit_ordering = !append;
 	LLCallAfterInventoryLinkMgr *link_waiter =
-		new LLCallAfterInventoryLinkMgr(body_items,cof,"update_appearance_on_destroy",
+		new LLCallAfterInventoryLinkMgr(all_items,cof,"update_appearance_on_destroy",
 										boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF,
 													LLAppearanceMgr::getInstance(),
 													update_base_outfit_ordering));
 
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL;
-#endif
-	link_waiter->addItems(wear_items);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL;
-#endif
-	link_waiter->addItems(obj_items);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL;
-#endif
-	link_waiter->addItems(gest_items);
-
 	// Add link to outfit if category is an outfit. 
 	if (!append)
 	{
@@ -1785,7 +1786,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
 	// carried over (e.g. keeping old shape if the new outfit does not
 	// contain one)
 	bool keep_outfit_links = append;
-	purgeCategory(cof, keep_outfit_links);
+	purgeCategory(cof, keep_outfit_links, &all_items);
 	gInventory.notifyObservers();
 
 	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index cb271cda4d..31dbce892a 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -206,8 +206,7 @@ private:
 								   LLInventoryModel::item_array_t& gest_items,
 								   bool follow_folder_links);
 
-	void purgeCategory(const LLUUID& category, bool keep_outfit_links);
-
+	void purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items = NULL);
 	static void onOutfitRename(const LLSD& notification, const LLSD& response);
 
 	void setOutfitLocked(bool locked);
-- 
cgit v1.2.3


From 67c66a12ab0e169e9e1e86265ff57aa5aa758b2a Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Tue, 18 Dec 2012 12:45:10 -0500
Subject: SH-3604 WIP - fixed a case with retry logic

---
 indra/newview/llappearancemgr.cpp | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 1044732f4b..4a484f3b85 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -199,14 +199,8 @@ public:
 	void addItem(const LLUUID& item_id)
 	{
 		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl;
-		
-		if (ll_frand()<gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
-		{
-			// simulate server failure by not sending the request.
-			// do nothing
-			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
-		}
-		else if (!requestOperation(item_id))
+
+		if (!requestOperation(item_id))
 		{
 			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;
 			return;
@@ -384,6 +378,11 @@ public:
 		LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		llassert(item);
 		LL_DEBUGS("Avatar") << "copying item " << item_id << llendl;
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+		{
+			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+			return true;
+		}
 		copy_inventory_item(
 			gAgent.getID(),
 			item->getPermissions().getOwner(),
@@ -425,6 +424,11 @@ public:
 			}
 			LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
 			// create an inventory item link.
+			if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+			{
+				LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+				return true;
+			}
 			link_inventory_item(gAgent.getID(),
 								item->getLinkedUUID(),
 								mDstCatID,
@@ -433,7 +437,7 @@ public:
 								LLAssetType::AT_LINK,
 								new LLBoostFuncInventoryCallback(
 									boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
-			request_sent = true;
+			return true;
 		}
 		else
 		{
@@ -451,6 +455,11 @@ public:
 
 			if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
 			{
+				if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+				{
+					LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+					return true;
+				}
 				LL_DEBUGS("Avatar") << "linking folder " << item_id << " name " << catp->getName() << " to cof " << cof << llendl;
 				link_inventory_item(gAgent.getID(), item_id, cof, catp->getName(), "",
 									LLAssetType::AT_LINK_FOLDER, 
-- 
cgit v1.2.3