re-apply roll-delay after seek - fixes #5781
[ardour.git] / libs / ardour / session_state.cc
index f893c18a1b18936a7d80da157461238eb146568c..d09385b8bfac2e6a8fe66c086bb8ca58e4741cf1 100644 (file)
@@ -50,7 +50,7 @@
 #endif
 
 #include <glib.h>
-#include <glib/gstdio.h>
+#include <pbd/gstdio_compat.h>
 
 #include <glibmm.h>
 #include <glibmm/threads.h>
@@ -2817,25 +2817,34 @@ Session::cleanup_regions ()
        bool removed = false;
        const RegionFactory::RegionMap& regions (RegionFactory::regions());
 
-       for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+       for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
 
                uint32_t used = playlists->region_use_count (i->second);
 
                if (used == 0 && !i->second->automatic ()) {
+                       boost::weak_ptr<Region> w = i->second;
+                       ++i;
                        removed = true;
-                       RegionFactory::map_remove (i->second);
+                       RegionFactory::map_remove (w);
+               } else {
+                       ++i;
                }
        }
 
        if (removed) {
                // re-check to remove parent references of compound regions
-               for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+               for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
                        if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
+                               ++i;
                                continue;
                        }
                        assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
                        if (0 == playlists->region_use_count (i->second)) {
-                               RegionFactory::map_remove (i->second);
+                               boost::weak_ptr<Region> w = i->second;
+                               ++i;
+                               RegionFactory::map_remove (w);
+                       } else {
+                               ++i;
                        }
                }
        }
@@ -2846,6 +2855,66 @@ Session::cleanup_regions ()
        save_state ("");
 }
 
+bool
+Session::can_cleanup_peakfiles () const
+{
+       if (deletion_in_progress()) {
+               return false;
+       }
+       if (!_writable || (_state_of_the_state & CannotSave)) {
+               warning << _("Cannot cleanup peak-files for read-only session.") << endmsg;
+               return false;
+       }
+        if (record_status() == Recording) {
+               error << _("Cannot cleanup peak-files while recording") << endmsg;
+               return false;
+       }
+       return true;
+}
+
+int
+Session::cleanup_peakfiles ()
+{
+       Glib::Threads::Mutex::Lock lm (peak_cleanup_lock, Glib::Threads::TRY_LOCK);
+       if (!lm.locked()) {
+               return -1;
+       }
+
+       assert (can_cleanup_peakfiles ());
+       assert (!peaks_cleanup_in_progres());
+
+       _state_of_the_state = StateOfTheState (_state_of_the_state | PeakCleanup);
+
+       int timeout = 5000; // 5 seconds
+       while (!SourceFactory::files_with_peaks.empty()) {
+               Glib::usleep (1000);
+               if (--timeout < 0) {
+                       warning << _("Timeout waiting for peak-file creation to terminate before cleanup, please try again later.") << endmsg;
+                       _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
+                       return -1;
+               }
+       }
+
+       for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
+               boost::shared_ptr<AudioSource> as;
+               if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
+                       as->close_peakfile();
+               }
+       }
+
+       PBD::clear_directory (session_directory().peak_path());
+
+       _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
+
+       for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
+               boost::shared_ptr<AudioSource> as;
+               if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
+                       SourceFactory::setup_peakfile(as, true);
+               }
+       }
+       return 0;
+}
+
 int
 Session::cleanup_sources (CleanupReport& rep)
 {