From: Robin Gareus Date: Tue, 15 Sep 2015 12:41:27 +0000 (+0200) Subject: prepare peak-file cleanup/recreate. X-Git-Tag: 4.3~402 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=04e7cfabbe58605e6770adbd9e27bf871a957bef;p=ardour.git prepare peak-file cleanup/recreate. --- diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index ad7884e4f4..345d424cf3 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -96,6 +96,7 @@ class LIBARDOUR_API AudioSource : virtual public Source, } virtual int setup_peakfile () { return 0; } + int close_peakfile (); int prepare_for_peakfile_writes (); void done_with_peakfile_writes (bool done = true); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 79eb2162da..6b71e3c1ed 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -191,6 +191,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop bool reconnection_in_progress() const { return _reconnecting_routes_in_progress; } bool deletion_in_progress() const { return _state_of_the_state & Deletion; } bool routes_deletion_in_progress() const { return _route_deletion_in_progress; } + bool peaks_cleanup_in_progres() const { return _state_of_the_state & PeakCleanup; } PBD::Signal0 DirtyChanged; @@ -505,7 +506,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop Deletion = 0x4, InitialConnecting = 0x8, Loading = 0x10, - InCleanup = 0x20 + InCleanup = 0x20, + PeakCleanup = 0x40 }; StateOfTheState state_of_the_state() const { return _state_of_the_state; } @@ -661,7 +663,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void add_source (boost::shared_ptr); void remove_source (boost::weak_ptr); - void cleanup_regions(); + void cleanup_regions(); + bool can_cleanup_peakfiles () const; + int cleanup_peakfiles (); int cleanup_sources (CleanupReport&); int cleanup_trash_sources (CleanupReport&); @@ -1243,6 +1247,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop gint _suspend_save; /* atomic */ volatile bool _save_queued; Glib::Threads::Mutex save_state_lock; + Glib::Threads::Mutex peak_cleanup_lock; int load_options (const XMLNode&); int load_state (std::string snapshot_name); diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 4439669c4f..d4be1df22e 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -752,8 +752,9 @@ AudioSource::build_peaks_from_scratch () lp.release(); // allow butler to refill buffers - if (_session.deletion_in_progress()) { + if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) { cerr << "peak file creation interrupted: " << _name << endmsg; + lp.acquire(); done_with_peakfile_writes (false); goto out; } @@ -788,9 +789,28 @@ AudioSource::build_peaks_from_scratch () return ret; } +int +AudioSource::close_peakfile () +{ + Glib::Threads::Mutex::Lock lp (_lock); + if (_peakfile_fd >= 0) { + close (_peakfile_fd); + _peakfile_fd = -1; + } + if (!_peakpath.empty()) { + ::g_unlink (_peakpath.c_str()); + } + _peaks_built = false; + return 0; +} + int AudioSource::prepare_for_peakfile_writes () { + if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) { + return -1; + } + if ((_peakfile_fd = g_open (_peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) { error << string_compose(_("AudioSource: cannot open _peakpath (c) \"%1\" (%2)"), _peakpath, strerror (errno)) << endmsg; return -1; @@ -801,6 +821,14 @@ AudioSource::prepare_for_peakfile_writes () void AudioSource::done_with_peakfile_writes (bool done) { + if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) { + if (_peakfile_fd) { + close (_peakfile_fd); + _peakfile_fd = -1; + } + return; + } + if (peak_leftover_cnt) { compute_and_write_peaks (0, 0, 0, true, false, _FPP); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index f893c18a1b..0c66b91578 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2846,6 +2846,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 as; + if ((as = boost::dynamic_pointer_cast (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 as; + if ((as = boost::dynamic_pointer_cast (i->second)) != 0) { + SourceFactory::setup_peakfile(as, true); + } + } + return 0; +} + int Session::cleanup_sources (CleanupReport& rep) {