Avoid possible dangling pointer problems with EVT_TRACKLIST_UPDATED

This commit is contained in:
Paul Licameli 2017-06-01 14:19:52 -04:00
parent f807f7fd6d
commit 721faf89c6
2 changed files with 20 additions and 1 deletions

View File

@ -856,6 +856,9 @@ void TrackList::UpdatedEvent(TrackNodePointer node)
else {
e.SetClientData(NULL);
}
// PRL: ProcessEvent, not QueueEvent! Listeners may need their last
// chance to examine some removed tracks that are about to be destroyed.
ProcessEvent(e);
}
@ -951,6 +954,9 @@ auto TrackList::Replace(Track * t, value_type &&with) -> value_type
*node = std::move(with);
pTrack->SetOwner(this, node);
RecalcPositions(node);
// PRL: Note: Send the event while t (now in holder) is not yet
// destroyed, so pointers to t that listeners may have are not dangling.
UpdatedEvent(node);
ResizedEvent(node);
}
@ -964,11 +970,15 @@ TrackNodePointer TrackList::Remove(Track *t)
auto node = t->GetNode();
if (!isNull(node)) {
value_type holder = std::move( *node );
result = erase(node);
if (!isNull(result)) {
RecalcPositions(result);
}
// PRL: Note: Send the event while t (now in holder) is not yet
// destroyed, so pointers to t that listeners may have are not dangling.
UpdatedEvent(end());
ResizedEvent(result);
}
@ -978,8 +988,12 @@ TrackNodePointer TrackList::Remove(Track *t)
void TrackList::Clear(bool sendEvent)
{
ListOfTracks::clear();
ListOfTracks tempList;
tempList.swap( *this );
if (sendEvent)
// PRL: Note: Send the event while tempList is not yet
// destroyed, so pointers to tracks that listeners may have are not
// dangling.
UpdatedEvent(end());
}

View File

@ -444,6 +444,11 @@ DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_RESIZED, -1);
// Posted when tracks have been added or deleted from a tracklist. The pointer
// wxCommandEvent::GetClientData() returns will be NULL for deletions or the
// track that was added.
// Also posted when one track replaces another
// Also posted when the list of tracks is permuted, but no addition or deletion
// When a track has been removed, the event is processed before the track
// is destroyed, so that listeners that stored a pointer to the track can still
// use it and correctly check whether the list still contains it.
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_UPDATED, -1);
class TrackList final : public wxEvtHandler, public ListOfTracks