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()
This commit is contained in:
Robin Gareus 2016-02-09 21:36:49 +01:00
parent d56a44bf36
commit 1ec78d26ee
4 changed files with 22 additions and 13 deletions

View File

@ -39,17 +39,22 @@ class LIBARDOUR_API ExportStatus {
/* Status info */ /* Status info */
volatile bool stop; volatile bool stop;
volatile bool running;
void abort (bool error_occurred = false); void abort (bool error_occurred = false);
bool aborted () const { return _aborted; } bool aborted () const { return _aborted; }
bool errors () const { return _errors; } 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<void> Finished; PBD::Signal0<void> Finished;
void finish (); void finish ();
bool finished () const { return _finished; }
void cleanup (); void cleanup ();
/* Progress info */ /* Progress info */
@ -77,8 +82,9 @@ class LIBARDOUR_API ExportStatus {
private: private:
volatile bool _aborted; volatile bool _aborted;
volatile bool _errors; volatile bool _errors;
volatile bool _finished; volatile bool _running;
Glib::Threads::Mutex _run_lock;
}; };
} // namespace ARDOUR } // namespace ARDOUR

View File

@ -150,6 +150,7 @@ ExportHandler::do_export ()
/* Start export */ /* Start export */
Glib::Threads::Mutex::Lock l (export_status->lock());
start_timespan (); start_timespan ();
} }
@ -160,7 +161,7 @@ ExportHandler::start_timespan ()
if (config_map.empty()) { if (config_map.empty()) {
// freewheeling has to be stopped from outside the process cycle // freewheeling has to be stopped from outside the process cycle
export_status->running = false; export_status->set_running (false);
return; return;
} }
@ -219,11 +220,13 @@ ExportHandler::handle_duplicate_format_extensions()
int int
ExportHandler::process (framecnt_t frames) ExportHandler::process (framecnt_t frames)
{ {
if (!export_status->running) { if (!export_status->running ()) {
return 0; return 0;
} else if (normalizing) { } else if (normalizing) {
Glib::Threads::Mutex::Lock l (export_status->lock());
return process_normalize (); return process_normalize ();
} else { } else {
Glib::Threads::Mutex::Lock l (export_status->lock());
return process_timespan (frames); return process_timespan (frames);
} }
} }

View File

@ -33,10 +33,10 @@ ExportStatus::ExportStatus ()
void void
ExportStatus::init () ExportStatus::init ()
{ {
Glib::Threads::Mutex::Lock l (_run_lock);
stop = false; stop = false;
running = false; _running = false;
_aborted = false; _aborted = false;
_finished = false;
_errors = false; _errors = false;
active_job = Exporting; active_job = Exporting;
@ -57,17 +57,17 @@ ExportStatus::init ()
void void
ExportStatus::abort (bool error_occurred) ExportStatus::abort (bool error_occurred)
{ {
Glib::Threads::Mutex::Lock l (_run_lock);
_aborted = true; _aborted = true;
_finished = true;
_errors = _errors || error_occurred; _errors = _errors || error_occurred;
running = false; _running = false;
} }
void void
ExportStatus::finish () ExportStatus::finish ()
{ {
_finished = true; Glib::Threads::Mutex::Lock l (_run_lock);
running = false; set_running (false);
Finished(); /* EMIT SIGNAL */ Finished(); /* EMIT SIGNAL */
} }

View File

@ -87,7 +87,7 @@ Session::pre_export ()
config.set_external_sync (false); config.set_external_sync (false);
_exporting = true; _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)); export_status->Finished.connect_same_thread (*this, boost::bind (&Session::finalize_audio_export, this));
/* disable MMC output early */ /* disable MMC output early */