Prevent crash at session-close when analysing.
authorRobin Gareus <robin@gareus.org>
Tue, 24 Nov 2015 23:55:41 +0000 (00:55 +0100)
committerRobin Gareus <robin@gareus.org>
Tue, 24 Nov 2015 23:56:05 +0000 (00:56 +0100)
The Analyser only holds a weak-pointer the the Source,
session-destruction frees the actual Source, which is fatal for any
ongoing audio analysis.

This fix simply waits for the current ongoing analysis to complete,
ideally TransientDetector::run, EBUr128Analysis::run, OnsetDetector::run
and AudioAnalyser::analyse could be interrupted.

Alternate option: cancel the Analyser::work thread (and re-create with
the every session).

libs/ardour/analyser.cc
libs/ardour/ardour/analyser.h
libs/ardour/session.cc

index fa22bd757da522d4135f4d1caafa15e58031dd1f..58a8f30245351698efec58f9c0c3a9e028f010ad 100644 (file)
@@ -31,6 +31,7 @@ using namespace ARDOUR;
 using namespace PBD;
 
 Analyser* Analyser::the_analyser = 0;
+Glib::Threads::Mutex Analyser::analysis_active_lock;
 Glib::Threads::Mutex Analyser::analysis_queue_lock;
 Glib::Threads::Cond  Analyser::SourcesToAnalyse;
 list<boost::weak_ptr<Source> > Analyser::analysis_queue;
@@ -96,6 +97,7 @@ Analyser::work ()
                boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
 
                if (afs && afs->length(afs->timeline_position())) {
+                       Glib::Threads::Mutex::Lock lm (analysis_active_lock);
                        analyse_audio_file_source (afs);
                }
        }
@@ -119,3 +121,11 @@ Analyser::analyse_audio_file_source (boost::shared_ptr<AudioFileSource> src)
                return;
        }
 }
+
+void
+Analyser::flush ()
+{
+       Glib::Threads::Mutex::Lock lq (analysis_queue_lock);
+       Glib::Threads::Mutex::Lock la (analysis_active_lock);
+       analysis_queue.clear();
+}
index 8e757ef4e9e17bfabdf54abce6f8e3a246a4a541..fec6bd21e3981647f00840c6b6e377d3b046b2ea 100644 (file)
@@ -40,11 +40,13 @@ class LIBARDOUR_API Analyser {
        static void init ();
        static void queue_source_for_analysis (boost::shared_ptr<Source>, bool force);
        static void work ();
+       static void flush ();
 
   private:
        static Analyser* the_analyser;
-        static Glib::Threads::Mutex analysis_queue_lock;
-        static Glib::Threads::Cond  SourcesToAnalyse;
+       static Glib::Threads::Mutex analysis_active_lock;
+       static Glib::Threads::Mutex analysis_queue_lock;
+       static Glib::Threads::Cond  SourcesToAnalyse;
        static std::list<boost::weak_ptr<Source> > analysis_queue;
 
        static void analyse_audio_file_source (boost::shared_ptr<AudioFileSource>);
index ec8b6e14cc34e5c90eb70213b5482a95dd864e66..856e89eced51d6a999d4101519c615658ee6bd0d 100644 (file)
@@ -544,6 +544,8 @@ Session::destroy ()
 
        remove_pending_capture_state ();
 
+       Analyser::flush ();
+
        _state_of_the_state = StateOfTheState (CannotSave|Deletion);
 
        /* disconnect from any and all signals that we are connected to */