Work around finish_capture() race
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.
This commit is contained in:
parent
464df06419
commit
fbfeff4168
@ -710,6 +710,7 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
/* not recording this time, but perhaps we were before .. */
|
/* not recording this time, but perhaps we were before .. */
|
||||||
|
|
||||||
if (_was_recording) {
|
if (_was_recording) {
|
||||||
|
Glib::Threads::Mutex::Lock lm (capture_info_lock);
|
||||||
finish_capture (c);
|
finish_capture (c);
|
||||||
_accumulated_capture_offset = 0;
|
_accumulated_capture_offset = 0;
|
||||||
_capture_start_sample.reset ();
|
_capture_start_sample.reset ();
|
||||||
@ -1157,6 +1158,7 @@ DiskWriter::use_new_write_source (DataType dt, uint32_t n)
|
|||||||
void
|
void
|
||||||
DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
|
DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
|
||||||
{
|
{
|
||||||
|
Glib::Threads::Mutex::Lock lm (capture_info_lock);
|
||||||
bool more_work = true;
|
bool more_work = true;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
SourceList audio_srcs;
|
SourceList audio_srcs;
|
||||||
@ -1186,7 +1188,6 @@ DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX is there anything we can do if err != 0 ? */
|
/* XXX is there anything we can do if err != 0 ? */
|
||||||
Glib::Threads::Mutex::Lock lm (capture_info_lock);
|
|
||||||
|
|
||||||
if (capture_info.empty()) {
|
if (capture_info.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -1326,6 +1327,7 @@ DiskWriter::loop (samplepos_t transport_sample)
|
|||||||
{
|
{
|
||||||
_transport_looped = false;
|
_transport_looped = false;
|
||||||
if (_was_recording) {
|
if (_was_recording) {
|
||||||
|
Glib::Threads::Mutex::Lock lm (capture_info_lock);
|
||||||
// all we need to do is finish this capture, with modified capture length
|
// all we need to do is finish this capture, with modified capture length
|
||||||
std::shared_ptr<ChannelList const> c = channels.reader();
|
std::shared_ptr<ChannelList const> c = channels.reader();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user