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

master
Todd Stinson 2012-08-13 16:55:51 -07:00
parent 1ace064a58
commit 7cbbdbd896
7 changed files with 51 additions and 18 deletions

View File

@ -651,8 +651,10 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
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
@ -668,7 +670,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
// ...name already exists in cache, fire callback now
fireSignal(agent_id, slot, av_name);
return;
return connection;
}
}
}
@ -681,7 +683,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
LLAvatarName av_name;
buildLegacyName(full_name, &av_name);
fireSignal(agent_id, slot, av_name);
return;
return connection;
}
}
}
@ -698,15 +700,17 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
// ...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;
}

View File

@ -71,10 +71,11 @@ namespace LLAvatarNameCache
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);

View File

@ -40,9 +40,10 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
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()

View File

@ -55,6 +55,7 @@ LLPathfindingObject::LLPathfindingObject()
mOwnerUUID(),
mHasOwnerName(false),
mOwnerName(),
mAvatarNameCacheConnection(),
mIsGroupOwned(false),
mLocation()
{
@ -67,6 +68,7 @@ LLPathfindingObject::LLPathfindingObject(const std::string &pUUID, const LLSD &p
mOwnerUUID(),
mHasOwnerName(false),
mOwnerName(),
mAvatarNameCacheConnection(),
mIsGroupOwned(false),
mLocation()
{
@ -80,6 +82,7 @@ LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther)
mOwnerUUID(pOther.mOwnerUUID),
mHasOwnerName(false),
mOwnerName(),
mAvatarNameCacheConnection(),
mIsGroupOwned(pOther.mIsGroupOwned),
mLocation(pOther.mLocation)
{
@ -88,6 +91,7 @@ LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther)
LLPathfindingObject::~LLPathfindingObject()
{
disconnectAvatarNameCacheConnection();
}
LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther)
@ -149,7 +153,7 @@ void LLPathfindingObject::fetchOwnerName()
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));
}
}
}
@ -159,4 +163,13 @@ void LLPathfindingObject::handleAvatarNameFetch(const LLUUID &pOwnerUUID, const
llassert(mOwnerUUID == pOwnerUUID);
mOwnerName = pAvatarName;
mHasOwnerName = true;
disconnectAvatarNameCacheConnection();
}
void LLPathfindingObject::disconnectAvatarNameCacheConnection()
{
if (mAvatarNameCacheConnection.connected())
{
mAvatarNameCacheConnection.disconnect();
}
}

View File

@ -32,6 +32,7 @@
#include <boost/shared_ptr.hpp>
#include "llavatarname.h"
#include "llavatarnamecache.h"
#include "lluuid.h"
#include "v3math.h"
@ -66,15 +67,17 @@ private:
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

View File

@ -45,6 +45,7 @@ LLPathfindingObjectList::LLPathfindingObjectList()
LLPathfindingObjectList::~LLPathfindingObjectList()
{
clear();
}
bool LLPathfindingObjectList::isEmpty() const
@ -52,6 +53,15 @@ 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)

View File

@ -47,6 +47,8 @@ public:
bool isEmpty() const;
void clear();
void update(LLPathfindingObjectPtr pUpdateObjectPtr);
void update(LLPathfindingObjectListPtr pUpdateObjectListPtr);
@ -56,7 +58,6 @@ public:
const_iterator begin() const;
const_iterator end() const;
protected:
LLPathfindingObjectMap &getObjectMap();