Commits

Stinson Linden committed 675f3a2

PATH-849: CRASHFIX This should fix the crash caused by LLPathfindingObject::handleAvatarNameFetch being called after the corresponding LLPathfindingObject has been deleted.

  • Participants
  • Parent commits 1c46f93

Comments (0)

Files changed (7)

File indra/llmessage/llavatarnamecache.cpp

 	signal(agent_id, av_name);
 }
 
-void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
+LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
 {
+	callback_connection_t connection;
+
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
 				{
 					// ...name already exists in cache, fire callback now
 					fireSignal(agent_id, slot, av_name);
-					return;
+					return connection;
 				}
 			}
 		}
 				LLAvatarName av_name;
 				buildLegacyName(full_name, &av_name);
 				fireSignal(agent_id, slot, av_name);
-				return;
+				return connection;
 			}
 		}
 	}
 	{
 		// ...new callback for this id
 		callback_signal_t* signal = new callback_signal_t();
-		signal->connect(slot);
+		connection = signal->connect(slot);
 		sSignalMap[agent_id] = signal;
 	}
 	else
 	{
 		// ...existing callback, bind additional slot
 		callback_signal_t* signal = sig_it->second;
-		signal->connect(slot);
+		connection = signal->connect(slot);
 	}
+
+	return connection;
 }
 
 

File indra/llmessage/llavatarnamecache.h

 		void (const LLUUID& agent_id, const LLAvatarName& av_name)>
 			callback_signal_t;
 	typedef callback_signal_t::slot_type callback_slot_t;
+	typedef boost::signals2::connection callback_connection_t;
 
 	// Fetches name information and calls callback.
 	// If name information is in cache, callback will be called immediately.
-	void get(const LLUUID& agent_id, callback_slot_t slot);
+	callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
 
 	// Allow display names to be explicitly disabled for testing.
 	void setUseDisplayNames(bool use);

File indra/llui/tests/llurlentry_stub.cpp

 	return false;
 }
 
-void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
+LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
 {
-	return;
+	callback_connection_t connection;
+	return connection;
 }
 
 bool LLAvatarNameCache::useDisplayNames()

File indra/newview/llpathfindingobject.cpp

 	mOwnerUUID(),
 	mHasOwnerName(false),
 	mOwnerName(),
+	mAvatarNameCacheConnection(),
 	mIsGroupOwned(false),
 	mLocation()
 {
 	mOwnerUUID(),
 	mHasOwnerName(false),
 	mOwnerName(),
+	mAvatarNameCacheConnection(),
 	mIsGroupOwned(false),
 	mLocation()
 {
 	mOwnerUUID(pOther.mOwnerUUID),
 	mHasOwnerName(false),
 	mOwnerName(),
+	mAvatarNameCacheConnection(),
 	mIsGroupOwned(pOther.mIsGroupOwned),
 	mLocation(pOther.mLocation)
 {
 
 LLPathfindingObject::~LLPathfindingObject()
 {
+	disconnectAvatarNameCacheConnection();
 }
 
 LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther)
 		mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName);
 		if (!mHasOwnerName)
 		{
-			LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2));
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2));
 		}
 	}
 }
 	llassert(mOwnerUUID == pOwnerUUID);
 	mOwnerName = pAvatarName;
 	mHasOwnerName = true;
+	disconnectAvatarNameCacheConnection();
 }
+
+void LLPathfindingObject::disconnectAvatarNameCacheConnection()
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+}

File indra/newview/llpathfindingobject.h

 #include <boost/shared_ptr.hpp>
 
 #include "llavatarname.h"
+#include "llavatarnamecache.h"
 #include "lluuid.h"
 #include "v3math.h"
 
 
 	void fetchOwnerName();
 	void handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName);
+	void disconnectAvatarNameCacheConnection();
 
-	LLUUID       mUUID;
-	std::string  mName;
-	std::string  mDescription;
-	LLUUID       mOwnerUUID;
-	bool         mHasOwnerName;
-	LLAvatarName mOwnerName;
-	BOOL         mIsGroupOwned;
-	LLVector3    mLocation;
+	LLUUID                                   mUUID;
+	std::string                              mName;
+	std::string                              mDescription;
+	LLUUID                                   mOwnerUUID;
+	bool                                     mHasOwnerName;
+	LLAvatarName                             mOwnerName;
+	LLAvatarNameCache::callback_connection_t mAvatarNameCacheConnection;
+	BOOL                                     mIsGroupOwned;
+	LLVector3                                mLocation;
 };
 
 #endif // LL_LLPATHFINDINGOBJECT_H

File indra/newview/llpathfindingobjectlist.cpp

 
 LLPathfindingObjectList::~LLPathfindingObjectList()
 {
+	clear();
 }
 
 bool LLPathfindingObjectList::isEmpty() const
 	return mObjectMap.empty();
 }
 
+void LLPathfindingObjectList::clear()
+{
+	for (LLPathfindingObjectMap::iterator objectIter = mObjectMap.begin(); objectIter != mObjectMap.end(); ++objectIter)
+	{
+		objectIter->second.reset();
+	}
+	mObjectMap.clear();
+}
+
 void LLPathfindingObjectList::update(LLPathfindingObjectPtr pUpdateObjectPtr)
 {
 	if (pUpdateObjectPtr != NULL)

File indra/newview/llpathfindingobjectlist.h

 
 	bool isEmpty() const;
 
+	void clear();
+
 	void update(LLPathfindingObjectPtr pUpdateObjectPtr);
 	void update(LLPathfindingObjectListPtr pUpdateObjectListPtr);
 
 	const_iterator begin() const;
 	const_iterator end() const;
 
-
 protected:
 	LLPathfindingObjectMap &getObjectMap();