diff options
| author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2012-11-30 17:41:07 -0500 | 
|---|---|---|
| committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2012-11-30 17:41:07 -0500 | 
| commit | 9934cd2e29c8ea11e0859cd881d286fd56fae96e (patch) | |
| tree | 3b6f6fc76bfd075005145ebcd022f0cdbe7e1ea7 | |
| parent | 47a2a2982de98c88fbc6cd17bdb897e5ec408b88 (diff) | |
SH-3562 WIP - detect possible hangs in item copying
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 137 | 
1 files changed, 121 insertions, 16 deletions
| diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9f6586a69b..09b0c132d2 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -154,6 +154,123 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string  	}  } +// Shim between inventory callback and boost function +typedef boost::function<void(const LLUUID&)> inventory_func_type; + +class LLBoostFuncInventoryCallback: public LLInventoryCallback +{ +public: + +	LLBoostFuncInventoryCallback(const inventory_func_type& func): +		mFunc(func) +	{ +	} + +	void fire(const LLUUID& item_id) +	{ +		mFunc(item_id); +	} + +private: +	inventory_func_type mFunc; +}; + +LLPointer<LLInventoryCallback> make_inventory_func_callback(const inventory_func_type& func) +{ +	return new LLBoostFuncInventoryCallback(func);  +} + +void report_fire(const LLUUID& item_id) +{ +	llinfos << item_id << llendl; +} + +class LLInventoryCopyMgr: public LLEventTimer  +{ +public: +	LLInventoryCopyMgr(LLInventoryModel::item_array_t& src_items, const LLUUID& dst_cat_id, +					   bool append, const std::string& phase): +		mDstCatID(dst_cat_id), +		mAppend(append), +		mTrackingPhase(phase), +		LLEventTimer(5.0) +	{ +		for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin(); +			 it != src_items.end(); +			 ++it) +		{ +			LLViewerInventoryItem* item = *it; +			mSrcTimes[item->getUUID()] = LLTimer(); +			requestCopy(item->getUUID()); +		} +		if (!mTrackingPhase.empty()) +		{ +			selfStartPhase(mTrackingPhase); +		} +	} + +	void requestCopy(const LLUUID& item_id) +	{ +		LLViewerInventoryItem *item = gInventory.getItem(item_id); +		if (!item) +		{ +			llwarns << "requestCopy item not found " << item_id << llendl; +			return; +		} +		copy_inventory_item( +			gAgent.getID(), +			item->getPermissions().getOwner(), +			item->getUUID(), +			mDstCatID, +			std::string(), +			make_inventory_func_callback(boost::bind(&LLInventoryCopyMgr::onCopy,this,item->getUUID(),_1)) +			); +	} +				 +	void onCopy(const LLUUID& src_id, const LLUUID& dst_id) +	{ +		LL_DEBUGS("Avatar") << "copied, src_id " << src_id << " to dst_id " << dst_id << " after " << mSrcTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; +		mSrcTimes.erase(src_id); +		if (mSrcTimes.empty()) +		{ +			onCompletion(); +		} +	} + +	void onCompletion() +	{ +		if (!mTrackingPhase.empty()) +		{ +			selfStopPhase(mTrackingPhase); +		} +		if( LLInventoryCallbackManager::is_instantiated() ) +		{ +			LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mDstCatID), mAppend); +		} +	} +	 +	// virtual +	// Will be deleted after returning true - only safe to do this if all callbacks have fired. +	BOOL tick() +	{ +		bool all_done = mSrcTimes.empty(); + +		if (!all_done) +		{ +			llwarns << "possible hang in copy, waiting on " << mSrcTimes.size() << " items" << llendl; +			// TODO possibly add retry logic here. + +		} +		return all_done; +	} + +private: +	std::string mTrackingPhase; +	std::map<LLUUID,LLTimer> mSrcTimes; +	LLUUID mDstCatID; +	bool mAppend; +}; +  class LLWearInventoryCategoryCallback : public LLInventoryCallback  {  public: @@ -1979,22 +2096,10 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap  			pid,  			LLFolderType::FT_NONE,  			name); -		LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(new_cat_id, append); -		it = items->begin(); -		for(; it < end; ++it) -		{ -			item = *it; -			if(item) -			{ -				copy_inventory_item( -					gAgent.getID(), -					item->getPermissions().getOwner(), -					item->getUUID(), -					new_cat_id, -					std::string(), -					cb); -			} -		} + +		// Create a CopyMgr that will copy items, manage its own destruction +		new LLInventoryCopyMgr(*items, new_cat_id, append, std::string("wear_inventory_category_callback")); +  		// BAP fixes a lag in display of created dir.  		gInventory.notifyObservers();  	} | 
