clean up memory leaks with nested source read buffers
authorPaul Davis <paul@linuxaudiosystems.com>
Sat, 28 May 2011 02:30:25 +0000 (02:30 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 28 May 2011 02:30:25 +0000 (02:30 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@9621 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/audiosource.h
libs/ardour/audio_playlist_source.cc
libs/ardour/audiosource.cc

index 93ad5d0767e027ea2eb68560c017fe1834a14d87..ded3e5e8624c96e02c31f12c3cc5134a7c677f15 100644 (file)
@@ -120,11 +120,12 @@ class AudioSource : virtual public Source,
           thread, or a lock around calls that use them. 
        */
 
-       static std::vector<Sample*> _mixdown_buffers;
-       static std::vector<gain_t*> _gain_buffers;
+       static std::vector<boost::shared_ptr<Sample> > _mixdown_buffers;
+       static std::vector<boost::shared_ptr<gain_t> > _gain_buffers;
        static Glib::StaticMutex    _level_buffer_lock;
 
        static void ensure_buffers_for_level (uint32_t, framecnt_t);
+       static void ensure_buffers_for_level_locked (uint32_t, framecnt_t);
 
        framecnt_t           _length;
        std::string         peakpath;
index 09b30ff87a628434b3d752673b0c9fd70159add0..f225db9c45e9b9e333f11321eaf406897c29a056 100644 (file)
@@ -130,8 +130,8 @@ AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_desc
 framecnt_t 
 AudioPlaylistSource::read_unlocked (Sample* dst, framepos_t start, framecnt_t cnt) const
 {
-       Sample* sbuf;
-       gain_t* gbuf;
+       boost::shared_ptr<Sample> sbuf;
+       boost::shared_ptr<gain_t> gbuf;
        framecnt_t to_read;
        framecnt_t to_zero;
        pair<framepos_t,framepos_t> extent = _playlist->get_extent();
@@ -160,7 +160,7 @@ AudioPlaylistSource::read_unlocked (Sample* dst, framepos_t start, framecnt_t cn
                gbuf = _gain_buffers[_level-1];
        }
 
-       boost::dynamic_pointer_cast<AudioPlaylist>(_playlist)->read (dst, sbuf, gbuf, start+_playlist_offset, to_read, _playlist_channel);
+       boost::dynamic_pointer_cast<AudioPlaylist>(_playlist)->read (dst, sbuf.get(), gbuf.get(), start+_playlist_offset, to_read, _playlist_channel);
 
        if (to_zero) {
                memset (dst+to_read, 0, sizeof (Sample) * to_zero);
index 9555f18fbe8833666419a3e5de91ec8e40e464c6..25e1d2222dec27ba4862b0235d51af0f983981a4 100644 (file)
@@ -51,8 +51,8 @@ using namespace ARDOUR;
 using namespace PBD;
 
 Glib::StaticMutex AudioSource::_level_buffer_lock = GLIBMM_STATIC_MUTEX_INIT;
-vector<Sample*> AudioSource::_mixdown_buffers;
-vector<gain_t*> AudioSource::_gain_buffers;
+vector<boost::shared_ptr<Sample> > AudioSource::_mixdown_buffers;
+vector<boost::shared_ptr<gain_t> > AudioSource::_gain_buffers;
 size_t AudioSource::_working_buffers_size = 0;
 bool AudioSource::_build_missing_peakfiles = false;
 
@@ -967,43 +967,37 @@ AudioSource::mark_streaming_write_completed ()
 void
 AudioSource::allocate_working_buffers (framecnt_t framerate)
 {
-       uint32_t current_level;
+       Glib::Mutex::Lock lm (_level_buffer_lock);
+       
        
-       {
-               Glib::Mutex::Lock lm (_level_buffer_lock);
-               current_level = _mixdown_buffers.size();
-       }
-
        /* Note: we don't need any buffers allocated until
           a level 1 audiosource is created, at which
           time we'll call ::ensure_buffers_for_level()
           with the right value and do the right thing.
        */
        
-       if (current_level) {
-               ensure_buffers_for_level (current_level, framerate);
+       if (!_mixdown_buffers.empty()) {
+               ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
        }
 }
 
 void
 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate) 
 {
-       framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
-
-       cerr << "audiosource: allocate buffers for level " << level << " size = " << nframes << endl;
-
        Glib::Mutex::Lock lm (_level_buffer_lock);
+       ensure_buffers_for_level_locked (level, frame_rate);
+}
 
-       /* this will leak memory. oh well. rather complex
-          to stop it from doing that without using shared_ptrs,
-          which i might do next. paul - may 27th 2011
-        */
+void
+AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate) 
+{
+       framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
 
        _mixdown_buffers.clear ();
        _gain_buffers.clear ();
 
        while (_mixdown_buffers.size() < level) {
-               _mixdown_buffers.push_back (new Sample[nframes]);
-               _gain_buffers.push_back (new gain_t[nframes]);
+               _mixdown_buffers.push_back (boost::shared_ptr<Sample> (new Sample[nframes]));
+               _gain_buffers.push_back (boost::shared_ptr<gain_t> (new gain_t[nframes]));
        }
 }