diff options
author | Mike Antipov <mantipov@productengine.com> | 2010-07-20 15:17:46 +0300 |
---|---|---|
committer | Mike Antipov <mantipov@productengine.com> | 2010-07-20 15:17:46 +0300 |
commit | d3d39b98aa0b0161be4e573c440ce642617d6d15 (patch) | |
tree | 592264033766c11bed3546b8e07aeb32db5d047c /indra | |
parent | 62040b686568410cdd87d12228b48f0b2ee12f1b (diff) |
EXT-8458 FIXED ensure that static pointer to instance of LLPanelStandStopFlying is always valid to prevent crash.
Consequences of root cause:
Static pointer to LLPanelStandStopFlying in LLPanelStandStopFlying::getInstance() becomes invalid when the instance of the LLPanelStandStopFlying is a child of floater while it is destroying.
Next usage of that pointed cause a crash.
Root Cause:
1. LLFloater::closeFloater sets floater invisible and marks floater as "dead" but does not destroy it.
2. But that instance was still in LLFloaterReg map. It is removed in LLFloater's destructor.
3. So it was possible on low fps to get "dead" floater with LLFloaterReg, LLFloaterMove in this case.
4. Then LLMortician deleted floater instance shown on previous step.
Call of setVisible(false) from the LLFloater's destructor does not call overridden LLFloaterMove's method (which is expected behavior.)
So, child panel LLPanelStandStopFlying was not re-parented to Main View and was destroyed with LLFloaterMove.
That leaded to the "Top Reason" described above.
FIX:
1. Ensure that LLPanelStandStopFlying is not a child of LLFloaterMove on its destroying.
2. Synchronized removing of a floater instance from the LLFloaterReg when it is marked as "dead".
Note: both changes fixes this bug independently, but I included both of them into result patch to avoid similar but in the future.
Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/781/
--HG--
branch : product-engine
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llui/llfloater.cpp | 8 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 2 | ||||
-rw-r--r-- | indra/newview/llmoveview.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llmoveview.h | 2 |
4 files changed, 20 insertions, 2 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 39a6855273..22d6f6ca52 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -451,6 +451,14 @@ void LLFloater::enableResizeCtrls(bool enable) } } +void LLFloater::destroy() +{ + // LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before + // it was deleted via LLMortician::updateClass(). See EXT-8458. + LLFloaterReg::removeInstance(mInstanceName, mKey); + die(); +} + // virtual LLFloater::~LLFloater() { diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3ea035777c..42f422f91c 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -308,7 +308,7 @@ protected: BOOL getAutoFocus() const { return mAutoFocus; } LLDragHandle* getDragHandle() const { return mDragHandle; } - void destroy() { die(); } // Don't call this directly. You probably want to call closeFloater() + void destroy(); // Don't call this directly. You probably want to call closeFloater() virtual void onClickCloseBtn(); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 6ae4a5e5e4..fc41137686 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -83,6 +83,16 @@ LLFloaterMove::LLFloaterMove(const LLSD& key) { } +LLFloaterMove::~LLFloaterMove() +{ + // Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458. + setVisible(FALSE); + + // Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid. + // Such situation was possible when LLFloaterReg returns "dead" instance of floater. + // Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg. +} + // virtual BOOL LLFloaterMove::postBuild() { diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index d463861188..43b0342744 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -51,7 +51,7 @@ class LLFloaterMove private: LLFloaterMove(const LLSD& key); - ~LLFloaterMove() {} + ~LLFloaterMove(); public: /*virtual*/ BOOL postBuild(); |