diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index 7ea7260688..36c79f6787 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -60,7 +60,7 @@ class AudioSource : virtual public Source, virtual float sample_rate () const = 0; - virtual void mark_streaming_write_completed () {} + virtual void mark_streaming_write_completed (); virtual bool can_truncate_peaks() const { return true; } @@ -111,8 +111,6 @@ class AudioSource : virtual public Source, static bool _build_peakfiles; framecnt_t _length; - bool _peaks_built; - mutable Glib::Mutex _peaks_ready_lock; std::string peakpath; std::string _captured_for; @@ -142,6 +140,15 @@ class AudioSource : virtual public Source, framecnt_t frames_per_peak); private: + bool _peaks_built; + /** This mutex is used to protect both the _peaks_built + * variable and also the emission (and handling) of the + * PeaksReady signal. Holding the lock when emitting + * PeaksReady means that _peaks_built cannot be changed + * during the handling of the signal. + */ + mutable Glib::Mutex _peaks_ready_lock; + PBD::FdFileDescriptor* _peakfile_descriptor; int _peakfile_fd; framecnt_t peak_leftover_cnt; diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index d3e050e4ba..30f8f84a5b 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -142,7 +142,6 @@ AudioFileSource::~AudioFileSource () int AudioFileSource::init (const string& pathstr, bool must_exist) { - _peaks_built = false; return FileSource::init (pathstr, must_exist); } @@ -287,15 +286,7 @@ AudioFileSource::mark_streaming_write_completed () return; } - /* XXX notice that we're readers of _peaks_built - but we must hold a solid lock on PeaksReady. - */ - - Glib::Mutex::Lock lm (_lock); - - if (_peaks_built) { - PeaksReady (); /* EMIT SIGNAL */ - } + AudioSource::mark_streaming_write_completed (); } int diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 9af388c1cd..360e4cd48a 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -165,10 +165,6 @@ AudioSource::peaks_ready (boost::function doThisWhenReady, ScopedConnect bool ret; Glib::Mutex::Lock lm (_peaks_ready_lock); - /* check to see if the peak data is ready. if not - connect the slot while still holding the lock. - */ - if (!(ret = _peaks_built)) { *connect_here_if_not = new ScopedConnection; PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop); @@ -683,13 +679,7 @@ AudioSource::build_peaks_from_scratch () } done_with_peakfile_writes ((cnt == 0)); - } - - { - Glib::Mutex::Lock lm (_peaks_ready_lock); - - if (_peaks_built) { - PeaksReady (); /* EMIT SIGNAL */ + if (cnt == 0) { ret = 0; } } @@ -723,7 +713,9 @@ AudioSource::done_with_peakfile_writes (bool done) } if (done) { + Glib::Mutex::Lock lm (_peaks_ready_lock); _peaks_built = true; + PeaksReady (); /* EMIT SIGNAL */ } delete _peakfile_descriptor; @@ -955,3 +947,13 @@ AudioSource::dec_read_data_count (nframes_t cnt) _read_data_count = 0; } } + +void +AudioSource::mark_streaming_write_completed () +{ + Glib::Mutex::Lock lm (_peaks_ready_lock); + + if (_peaks_built) { + PeaksReady (); /* EMIT SIGNAL */ + } +}