From 1ec78d26ee7cd5a612a7f98f9977dbb8ef46a593 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 9 Feb 2016 21:36:49 +0100 Subject: Fix crash when aborting export. The "Stop" button results in ExportHandlerPtr being destroyed. This must not happen while it's in use -- in particular during ExportHandler::start_timespan() and ExportHandler::finish_timespan() --- libs/ardour/ardour/export_status.h | 14 ++++++++++---- libs/ardour/export_handler.cc | 7 +++++-- libs/ardour/export_status.cc | 12 ++++++------ libs/ardour/session_export.cc | 2 +- 4 files changed, 22 insertions(+), 13 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/export_status.h b/libs/ardour/ardour/export_status.h index 6c6396dc5f..95921629c7 100644 --- a/libs/ardour/ardour/export_status.h +++ b/libs/ardour/ardour/export_status.h @@ -39,17 +39,22 @@ class LIBARDOUR_API ExportStatus { /* Status info */ volatile bool stop; - volatile bool running; void abort (bool error_occurred = false); bool aborted () const { return _aborted; } bool errors () const { return _errors; } + bool running () const { return _running; } + + void set_running (bool r) { + assert (!_run_lock.trylock()); // must hold lock + _running = r; + } + Glib::Threads::Mutex& lock () { return _run_lock; } PBD::Signal0 Finished; void finish (); - bool finished () const { return _finished; } - void cleanup (); + void cleanup (); /* Progress info */ @@ -77,8 +82,9 @@ class LIBARDOUR_API ExportStatus { private: volatile bool _aborted; volatile bool _errors; - volatile bool _finished; + volatile bool _running; + Glib::Threads::Mutex _run_lock; }; } // namespace ARDOUR diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc index 71f79b793c..70c807b7de 100644 --- a/libs/ardour/export_handler.cc +++ b/libs/ardour/export_handler.cc @@ -150,6 +150,7 @@ ExportHandler::do_export () /* Start export */ + Glib::Threads::Mutex::Lock l (export_status->lock()); start_timespan (); } @@ -160,7 +161,7 @@ ExportHandler::start_timespan () if (config_map.empty()) { // freewheeling has to be stopped from outside the process cycle - export_status->running = false; + export_status->set_running (false); return; } @@ -219,11 +220,13 @@ ExportHandler::handle_duplicate_format_extensions() int ExportHandler::process (framecnt_t frames) { - if (!export_status->running) { + if (!export_status->running ()) { return 0; } else if (normalizing) { + Glib::Threads::Mutex::Lock l (export_status->lock()); return process_normalize (); } else { + Glib::Threads::Mutex::Lock l (export_status->lock()); return process_timespan (frames); } } diff --git a/libs/ardour/export_status.cc b/libs/ardour/export_status.cc index 66f02c59c3..4b48a8edd7 100644 --- a/libs/ardour/export_status.cc +++ b/libs/ardour/export_status.cc @@ -33,10 +33,10 @@ ExportStatus::ExportStatus () void ExportStatus::init () { + Glib::Threads::Mutex::Lock l (_run_lock); stop = false; - running = false; + _running = false; _aborted = false; - _finished = false; _errors = false; active_job = Exporting; @@ -57,17 +57,17 @@ ExportStatus::init () void ExportStatus::abort (bool error_occurred) { + Glib::Threads::Mutex::Lock l (_run_lock); _aborted = true; - _finished = true; _errors = _errors || error_occurred; - running = false; + _running = false; } void ExportStatus::finish () { - _finished = true; - running = false; + Glib::Threads::Mutex::Lock l (_run_lock); + set_running (false); Finished(); /* EMIT SIGNAL */ } diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index ea4a07dd1f..8908716965 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -87,7 +87,7 @@ Session::pre_export () config.set_external_sync (false); _exporting = true; - export_status->running = true; + export_status->set_running (true); export_status->Finished.connect_same_thread (*this, boost::bind (&Session::finalize_audio_export, this)); /* disable MMC output early */ -- cgit v1.2.3