summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2010-02-04 10:20:31 -0500
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2010-02-04 10:20:31 -0500
commitd2d192060993d938a2fd131f8872a60b678e4a04 (patch)
treee7141b495ee94e4bed68f9e59001cdbf273036b0 /indra/newview
parent9b44d686d8e92011ea2704a3fe1978e0f57aed7d (diff)
For EXT-4855: Crash on onWearableAssetFetch. Prevent late-arriving wearables from touching a deleted object.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llappearancemgr.cpp47
1 files changed, 30 insertions, 17 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 585d42f66d..0fe236c056 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -321,7 +321,7 @@ public:
~LLWearableHoldingPattern();
bool pollCompletion();
- bool isDone();
+ bool isFetchCompleted();
bool isTimedOut();
typedef std::list<LLFoundData> found_list_t;
@@ -330,10 +330,12 @@ public:
LLInventoryModel::item_array_t mGestItems;
S32 mResolved;
LLTimer mWaitTime;
+ bool mFired;
};
LLWearableHoldingPattern::LLWearableHoldingPattern():
- mResolved(0)
+ mResolved(0),
+ mFired(false)
{
}
@@ -341,31 +343,34 @@ LLWearableHoldingPattern::~LLWearableHoldingPattern()
{
}
-bool LLWearableHoldingPattern::isDone()
+bool LLWearableHoldingPattern::isFetchCompleted()
{
- if (mResolved >= (S32)mFoundList.size())
- return true; // have everything we were waiting for
- else if (isTimedOut())
- {
- llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl;
- return true;
- }
- return false;
-
+ return (mResolved >= (S32)mFoundList.size()); // have everything we were waiting for?
}
bool LLWearableHoldingPattern::isTimedOut()
{
- static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
+ static F32 max_wait_time = 20.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
return mWaitTime.getElapsedTimeF32() > max_wait_time;
}
bool LLWearableHoldingPattern::pollCompletion()
{
- bool done = isDone();
- llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
+ bool completed = isFetchCompleted();
+ bool timed_out = isTimedOut();
+ bool done = completed || timed_out;
+
+ llinfos << "polling, done status: " << completed << " timed out? " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
+
if (done)
{
+ mFired = true;
+
+ if (timed_out)
+ {
+ llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
+ }
+
// Activate all gestures in this folder
if (mGestItems.count() > 0)
{
@@ -397,7 +402,11 @@ bool LLWearableHoldingPattern::pollCompletion()
LLAgentWearables::userUpdateAttachments(mObjItems);
}
- delete this;
+ if (completed)
+ {
+ // Only safe to delete if all wearable callbacks completed.
+ delete this;
+ }
}
return done;
}
@@ -432,7 +441,11 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
static void onWearableAssetFetch(LLWearable* wearable, void* data)
{
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
-
+ if (holder->mFired)
+ {
+ llwarns << "called after holder fired" << llendl;
+ }
+
if(wearable)
{
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();