summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-12-12 09:54:36 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2016-12-12 09:54:36 +0000
commita18231c749dc60103c3a24107ddf199880c6785c (patch)
treecf21e6f2ba2431c9fcec900826f0395dcd373055
parent8fcb7a5ee339d80ab8ad752defbb6aebee8e4158 (diff)
downloadardour-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.cc23
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);
}