summaryrefslogtreecommitdiff
path: root/indra/newview/llconversationview.cpp
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-01-06 00:45:07 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-01-06 01:33:26 +0200
commitf86014ef151c7af64de4a08dc4c320e1743fb34b (patch)
tree96047a3d76efa4ffaa92d6f9d398c4e398b9663b /indra/newview/llconversationview.cpp
parentdb161b6f85a266ee9d883e3180874de898ccda0e (diff)
SL-14270 Crash on participant's updateName
Session was deleted before viewer had a chance to create view for listener, so listener ended up not deleted and avaiting an uptade, then tryed to call for deleted session.
Diffstat (limited to 'indra/newview/llconversationview.cpp')
-rw-r--r--indra/newview/llconversationview.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 25971a7d52..71346b4b43 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -103,6 +103,57 @@ LLConversationViewSession::~LLConversationViewSession()
mFlashTimer->unset();
}
+void LLConversationViewSession::destroyView()
+{
+ // Chat can create and parent models(listeners) to session's model before creating
+ // coresponding views, such participant's models normally will wait for idle cycles
+ // but since we are deleting session and won't be processing any more events, make
+ // sure unowned models are removed as well.
+ // Might be good idea to just have an LLPointer list somewhere in LLConversationItemSession
+
+ LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
+
+ // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent
+ // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant)
+ if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1)
+ {
+ // Destroy existing views
+ while (!mItems.empty())
+ {
+ LLFolderViewItem *itemp = mItems.back();
+ mItems.pop_back();
+
+ LLFolderViewModelItem* item_vmi = itemp->getViewModelItem();
+ if (item_vmi) // supposed to exist
+ {
+ // unparent to remove from child list
+ vmi->removeChild(item_vmi);
+ }
+ itemp->destroyView();
+ }
+
+ // Not needed in scope of sessions, but just in case
+ while (!mFolders.empty())
+ {
+ LLFolderViewFolder *folderp = mFolders.back();
+ mFolders.pop_back();
+
+ LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem();
+ if (folder_vmi)
+ {
+ vmi->removeChild(folder_vmi);
+ }
+ folderp->destroyView();
+ }
+
+ // Now everything that is left in model(listener) is unowned,
+ // it is safe to remove
+ vmi->deleteParticipantModels();
+ }
+
+ LLFolderViewFolder::destroyView();
+}
+
void LLConversationViewSession::setFlashState(bool flash_state)
{
if (flash_state && !mFlashStateOn)