SL-15061 Crash deleting non-zero reference in LLConversationItemSession
parent
6240168f24
commit
18323f019f
|
|
@ -350,16 +350,24 @@ void LLConversationItemSession::clearParticipants()
|
|||
}
|
||||
|
||||
|
||||
void LLConversationItemSession::deleteParticipantModels()
|
||||
void LLConversationItemSession::clearAndDeparentModels()
|
||||
{
|
||||
// Make sure that no views exist before use and that view-owned items were removed!
|
||||
//
|
||||
// Normally we are not supposed to delete models directly, they should be
|
||||
// owned by views and this action will result in crashes, but LLParticipantList
|
||||
// creates models separately from views (it probably shouldn't) and then those
|
||||
// models wait for idle cycles to be assigned to view.
|
||||
// this code is meant to delete 'waiting' models
|
||||
std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
|
||||
std::for_each(mChildren.begin(), mChildren.end(),
|
||||
[](LLFolderViewModelItem* c)
|
||||
{
|
||||
if (c->getNumRefs() == 0)
|
||||
{
|
||||
// LLConversationItemParticipant can be created but not assigned to any view,
|
||||
// it was waiting for an "add_participant" event to be processed
|
||||
delete c;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Model is still assigned to some view/widget
|
||||
c->setParent(NULL);
|
||||
}
|
||||
}
|
||||
);
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ public:
|
|||
void removeParticipant(LLConversationItemParticipant* participant);
|
||||
void removeParticipant(const LLUUID& participant_id);
|
||||
void clearParticipants();
|
||||
void deleteParticipantModels(); // do not use while there are existing participant views
|
||||
void clearAndDeparentModels(); // will delete unowned models and deparent owned ones
|
||||
LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
|
||||
|
||||
void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
|
||||
|
|
|
|||
|
|
@ -108,8 +108,7 @@ 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
|
||||
// sure unowned LLConversationItemParticipant models are removed as well.
|
||||
|
||||
LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
|
||||
|
||||
|
|
@ -146,9 +145,9 @@ void LLConversationViewSession::destroyView()
|
|||
folderp->destroyView();
|
||||
}
|
||||
|
||||
// Now everything that is left in model(listener) is unowned,
|
||||
// it is safe to remove
|
||||
vmi->deleteParticipantModels();
|
||||
// Now everything that is left in model(listener) is not owned by views,
|
||||
// only by sessions, deparent so it won't point to soon to be dead model
|
||||
vmi->clearAndDeparentModels();
|
||||
}
|
||||
|
||||
LLFolderViewFolder::destroyView();
|
||||
|
|
|
|||
Loading…
Reference in New Issue