Fix crash when aborting export.
authorRobin Gareus <robin@gareus.org>
Tue, 9 Feb 2016 20:36:49 +0000 (21:36 +0100)
committerRobin Gareus <robin@gareus.org>
Tue, 9 Feb 2016 20:36:49 +0000 (21:36 +0100)
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
libs/ardour/export_handler.cc
libs/ardour/export_status.cc
libs/ardour/session_export.cc

index 6c6396dc5f6d568f4b2c42f1e5d5a35083669d0d..95921629c7e327900600666492d9c87faaf9d82e 100644 (file)
@@ -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<void>      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
index 71f79b793cb678271ae61439ee015b9ec2173abc..70c807b7de5d35f43251b80290889b5e88b80be4 100644 (file)
@@ -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);
        }
 }
index 66f02c59c31cc41b305834e8abb906a7fcb5041a..4b48a8edd72d0ab8174658639caf10cf08550861 100644 (file)
@@ -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 */
 }
 
index ea4a07dd1f66cd883a0aa4a4ba1f87d9d1cc92eb..890871696517c7986622ef77212208df0ab08272 100644 (file)
@@ -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 */