Besides, it can happen under normal circumstances that the
Editor window, or any other window with clocks (prefs) is
visible while no session is loaded.
In rare cases DiskWriter::run() may call finish_capture()
concurrently with the butler thread from transport_stopped_wallclock,
this can lead to memory corruption (CaptureInfo).
Using a Mutex here is not great, but it is not usually contended
and better than crashing at rec-stop.
We should probably change DiskWrWiter::_was_recording into an
atomic bool, and use CAS to prevent concurrent calls.
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.
The GUI was able to free memory (MidiTracer::disconnect),
while the tracer is concurrently still in use in rt-context.
This lead to memory corruption in MIDI::Parser::scanner.
This fixes undo/redo action sensitivity for non-editor
history stack changes.
Notably recording was not undoable, because the butler
thread creates the reversible "capture" command.
port-meta-data depends on the audioengine backend/device
settings. Those are only available after the engine is started,
not from within the backend's _start() method.
This is is only relevant for callback based backends.
Backends with a blocking process thread explicitly emit
port-manager callbacks there before entering the main loop.
Because those Widgets are added to managed frames (for search highlight)
the labels inside also need to be managed and not destroyed with the
Option (which happens first).
This fixes various GTK warnings at exit
```
gtk_widget_unparent: assertion 'GTK_IS_WIDGET (widget)' failed
```
Record, move recorded region(s), delete the recorded source, undo.
Undo would undo the region-move, of a region that no longer
exists and has no source.
This fixes the following issue:
1. Import a file to a new track
2. Delete the track
3. Editor Source list: select imported file,
-> Remove the selected source
-> Yes, remove the Regions and Sources
The Track and Region no longer exist in the Editor,
only the playlist still exists!
The sources to be deleted are found when iterating over whole-file
regions in `EditorSources::remove_selected_sources`. Also
RegionFactory::get_regions_using_source correctly returns
regions, _editor->remove_regions does nothing since there
is no RegionView for the given region(s). This then cashes in
```
libs/ardour/playlist.cc:2400: virtual XMLNode& ARDOUR::Playlist::state(bool) const: Assertion `r->sources ().size () > 0 && r->master_sources ().size () > 0' failed.
```
The eventual goal is to keep the set of used regions
in sync, and allow to remove explicit calls to
`sync_all_regions_with_regions`.
This prevents `all_regions` to retain a reference to
a region that has been destroyed.
* Do not emit signal with source-lock mutex held
* explicitly drop references when called directly; notably from
EditorSources::remove_selected_sources
It is not sufficient to simply drop the first source
of a region. While destroying a whole-file region marks
all its sources as unused, only the source for 1st channel
was explicitly removed.
The session accumulated <Sources>, without corresponding
whole-file Regions. Those can prevent cleanup of unused
sources, particularly when using snapshots.
* It was never called because SourceListBase::set_session
subscribed to the signal just before SessionHandle::set_session
dropped _session_connections
* remove_source() only checked the first source of the whole-file
region, not all sources of a multi-channel region.
Stereo regions with mono sources are now properly cleaned up.