Fix signal emission order ambiguity (record regionview)
A rec-region is added to the streamview just like any other region (::add_region_view_internal). This subscribes to region->DropReferences. When the DropReferences is handled first by StreamView::remove_region_view the corresponding RegionView is destroyed. This can happen even while recording is still active, eg. when locating (which stops the current recording). MidiStreamView::setup_rec_box() is called and crashes in `dynamic_cast<MidiRegionView*> (rec_regions.back().second);` due to a use after free. Strictly speaking this is a logic error in how ::setup_rec_box() determines if to add or remove the rec-box. But due to the asynchronous nature of signal emission and transport-state changes the best solution is to destroy the rec-region at the same when the RegionView is destroyed. To reproduce: * create a session with a MIDI track * disconnect the input (empty MIDI regions are removed) * Preferences > Transport > *enable* latched-record-enable * use the Dummy backend's MIDI generator * connect Hardware > MIDI > MMC -> Ardour misc > MMC in OR use JACK-transport to locate while recording.
This commit is contained in:
parent
ad5d355fb5
commit
464df06419
@ -193,6 +193,23 @@ StreamView::remove_region_view (std::weak_ptr<Region> weak_r)
|
||||
return;
|
||||
}
|
||||
|
||||
bool clear_rec_rects = false;
|
||||
for (list<pair<std::shared_ptr<Region>,RegionView*> >::iterator i = rec_regions.begin(); i != rec_regions.end();) {
|
||||
if (i->first == r) {
|
||||
i = rec_regions.erase (i);
|
||||
clear_rec_rects = true;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (clear_rec_rects) {
|
||||
for (auto const& i : rec_rects) {
|
||||
delete i.rectangle;
|
||||
}
|
||||
rec_rects.clear();
|
||||
}
|
||||
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (((*i)->region()) == r) {
|
||||
RegionView* rv = *i;
|
||||
@ -477,7 +494,8 @@ StreamView::cleanup_rec_box ()
|
||||
rec_active = false;
|
||||
|
||||
/* remove temp regions */
|
||||
for (auto const& i : rec_regions) {
|
||||
auto rr (rec_regions);
|
||||
for (auto const& i : rr) {
|
||||
i.first->drop_references ();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user