diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-12-12 09:54:36 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-12-12 09:54:36 +0000 |
commit | a18231c749dc60103c3a24107ddf199880c6785c (patch) | |
tree | cf21e6f2ba2431c9fcec900826f0395dcd373055 | |
parent | 8fcb7a5ee339d80ab8ad752defbb6aebee8e4158 (diff) | |
download | ardour-origin/pd_midicleanup.zip ardour-origin/pd_midicleanup.tar.gz ardour-origin/pd_midicleanup.tar.bz2 |
when adding notes a MidiModel/Sequence via NoteDiffCommand, copy the NotePtr first.origin/pd_midicleanup
The NotePtr ends up in an intrusive list, which causes ownership
issues. See comments for more.
-rw-r--r-- | libs/ardour/midi_model.cc | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index af99c0f..d64a881 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -246,7 +246,20 @@ MidiModel::NoteDiffCommand::operator() () for (NoteList::iterator i = _added_notes.begin(); i != _added_notes.end(); ++i) { - if (!_model->add_note_unlocked (*i)) { + /* We need to copy the NotePtr. If we add the actual + * NotePtr held in _added_notes, then it is inserted + * into the intrusive containers used by the + * MidiModel/Sequence. But we continue to hold a + * reference to it (since this NoteDiffCommand has a + * long life), and our destructor will attempt to + * destroy it. If the destructor for the NotePtr finds + * that it is linked into an intrusive list, it will + * abort. + */ + + NotePtr* copy = new NotePtr (*i); + + if (!_model->add_note_unlocked (*copy)) { /* failed to add it, so don't leave it in the removed list, to avoid apparent errors on undo. */ @@ -255,6 +268,14 @@ MidiModel::NoteDiffCommand::operator() () } for (NoteList::iterator i = _removed_notes.begin(); i != _removed_notes.end(); ++i) { + + /* We are asking the MidiModel/Sequence to remove the + * NotePtr that evaluates operator== (*i) as true + * ... that is, a NotePtr that points to the same Note + * as *i. The actual NotePtr will not be identical (see + * the _added_notes case above. + */ + _model->remove_note_unlocked (*i); } |