From bca0450c188cdac82fbc74d05b5d72aff9115646 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 16 Mar 2007 04:09:03 +0000 Subject: possible fix for crash while adding new tracks git-svn-id: svn://localhost/ardour2/trunk@1603 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audio_diskstream.h | 10 +++++----- libs/ardour/ardour/diskstream.h | 4 ++-- libs/ardour/ardour/session.h | 6 ++++-- libs/ardour/audio_diskstream.cc | 20 +++++++------------- libs/ardour/audio_track.cc | 1 + libs/ardour/diskstream.cc | 5 +---- libs/ardour/session.cc | 20 ++++++++++++++------ libs/ardour/session_events.cc | 12 ++++++++++++ libs/ardour/session_transport.cc | 25 ++++++++++++++++++++++--- 9 files changed, 68 insertions(+), 35 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 1da8903a41..cb70903d13 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -212,7 +212,7 @@ class AudioDiskstream : public Diskstream int do_flush (Session::RunContext context, bool force = false); int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); } - int do_refill_with_alloc(); + int do_refill_with_alloc (); int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, nframes_t& start, nframes_t cnt, @@ -251,14 +251,14 @@ class AudioDiskstream : public Diskstream static Sample* _mixdown_buffer; static gain_t* _gain_buffer; - // Uh, /really/ private? (there should probably be less friends of Diskstream) - int _do_refill (Sample *mixdown_buffer, float *gain_buffer); - - std::vector > capturing_sources; typedef vector ChannelList; ChannelList channels; + + /* really */ + private: + int _do_refill (Sample *mixdown_buffer, float *gain_buffer); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index e3907125f2..a03b778dd9 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -21,6 +21,7 @@ #define __ardour_diskstream_h__ #include +#include #include #include @@ -53,7 +54,7 @@ class Session; class Playlist; class IO; - class Diskstream : public PBD::StatefulDestructible +class Diskstream : public PBD::StatefulDestructible, public boost::enable_shared_from_this { public: enum Flag { @@ -199,7 +200,6 @@ class IO; /** For non-butler contexts (allocates temporary working buffers) */ virtual int do_refill_with_alloc() = 0; - /* XXX fix this redundancy ... */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index d65903ce85..9955dd9311 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -164,7 +164,8 @@ class Session : public PBD::StatefulDestructible SlaveSource slave; }; - boost::shared_ptr region; + boost::shared_ptr region; + boost::shared_ptr diskstream; list audio_range; list music_range; @@ -361,7 +362,7 @@ class Session : public PBD::StatefulDestructible void request_transport_speed (float speed); void request_overwrite_buffer (Diskstream*); void request_diskstream_speed (Diskstream&, float speed); - void request_input_change_handling (); + void request_input_change_handling (boost::shared_ptr); bool locate_pending() const { return static_cast(post_transport_work&PostTransportLocate); } bool transport_locked () const; @@ -1424,6 +1425,7 @@ class Session : public PBD::StatefulDestructible /* disk-streams */ SerializedRCUManager diskstreams; + SerializedRCUManager diskstreams_input_pending; uint32_t dstream_buffer_size; int load_diskstreams (const XMLNode&); diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 1a117661e3..e72519ef7d 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -912,25 +913,25 @@ AudioDiskstream::overwrite_existing_buffers () int AudioDiskstream::seek (nframes_t frame, bool complete_refill) { - Glib::Mutex::Lock lm (state_lock); uint32_t n; int ret; ChannelList::iterator chan; - + Glib::Mutex::Lock lm (state_lock); + for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) { (*chan).playback_buf->reset (); (*chan).capture_buf->reset (); } /* can't rec-enable in destructive mode if transport is before start */ - + if (destructive() && record_enabled() && frame < _session.current_start_frame()) { disengage_record_enable (); } - + playback_sample = frame; file_frame = frame; - + if (complete_refill) { while ((ret = do_refill_with_alloc ()) > 0) ; } else { @@ -1065,7 +1066,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, } int -AudioDiskstream::do_refill_with_alloc() +AudioDiskstream::do_refill_with_alloc () { Sample* mix_buf = new Sample[disk_io_chunk_frames]; float* gain_buf = new float[disk_io_chunk_frames]; @@ -1100,7 +1101,6 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) vector.len[1] = 0; channels.front().playback_buf->get_write_vector (&vector); - if ((total_space = vector.len[0] + vector.len[1]) == 0) { return 0; @@ -1833,9 +1833,6 @@ AudioDiskstream::set_state (const XMLNode& node) if (nchans > _n_channels) { - // we need to add new channel infos - //LockMonitor lm (state_lock, __LINE__, __FILE__); - int diff = nchans - channels.size(); for (int i=0; i < diff; ++i) { @@ -1844,9 +1841,6 @@ AudioDiskstream::set_state (const XMLNode& node) } else if (nchans < _n_channels) { - // we need to get rid of channels - //LockMonitor lm (state_lock, __LINE__, __FILE__); - int diff = channels.size() - nchans; for (int i = 0; i < diff; ++i) { diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index e390c067ff..7c25a8c899 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -60,6 +60,7 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode } boost::shared_ptr ds (new AudioDiskstream (_session, name, dflags)); + _session.add_diskstream (ds); set_diskstream (boost::dynamic_pointer_cast (ds), this); diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 812709cda1..f643bbe2c0 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -125,9 +125,6 @@ Diskstream::init (Flag f) Diskstream::~Diskstream () { - // Taken by derived class destrctors.. should assure locked here somehow? - //Glib::Mutex::Lock lm (state_lock); - if (_playlist) _playlist->release (); } @@ -146,7 +143,7 @@ Diskstream::handle_input_change (IOChange change, void *src) if (!(input_change_pending & change)) { input_change_pending = IOChange (input_change_pending|change); - _session.request_input_change_handling (); + _session.request_input_change_handling (shared_from_this()); } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 257126b6f1..951339db98 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -269,6 +269,7 @@ Session::Session (AudioEngine &eng, pending_events (2048), midi_requests (128), // the size of this should match the midi request pool size diskstreams (new DiskstreamList), + diskstreams_input_pending (new DiskstreamList), routes (new RouteList), auditioner ((Auditioner*) 0), _click_io ((IO*) 0), @@ -332,6 +333,7 @@ Session::Session (AudioEngine &eng, pending_events (2048), midi_requests (16), diskstreams (new DiskstreamList), + diskstreams_input_pending (new DiskstreamList), routes (new RouteList), main_outs (0) @@ -2002,21 +2004,23 @@ void Session::add_diskstream (boost::shared_ptr dstream) { /* need to do this in case we're rolling at the time, to prevent false underruns */ - dstream->do_refill_with_alloc(); + dstream->do_refill_with_alloc (); - { + dstream->set_block_size (current_block_size); + + if (_state_of_the_state & InitialConnecting) { RCUWriter writer (diskstreams); boost::shared_ptr ds = writer.get_copy(); ds->push_back (dstream); - } - - dstream->set_block_size (current_block_size); + /* writer goes out of scope, copies ds back to main */ + } dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream)); /* this will connect to future changes, and check the current length */ diskstream_playlist_changed (dstream); dstream->prepare (); + } void @@ -3383,7 +3387,11 @@ Session::graph_reordered () we were connecting. do it now. */ - request_input_change_handling (); + boost::shared_ptr ds = diskstreams.reader(); + + for (DiskstreamList::iterator i = ds->begin(); i != ds->end(); ++i) { + request_input_change_handling (*i); + } resort_routes (); diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index e93a7a5f17..416d72969e 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -410,6 +410,18 @@ Session::process_event (Event* ev) case Event::InputConfigurationChange: post_transport_work = PostTransportWork (post_transport_work | PostTransportInputChange); + { + RCUWriter writer (diskstreams); + boost::shared_ptr ds = writer.get_copy(); + ds->remove (ev->diskstream); + /* writer goes out of scope, copies ds back to main */ + } + { + RCUWriter writer (diskstreams_input_pending); + boost::shared_ptr ds = writer.get_copy(); + ds->push_back (ev->diskstream); + /* writer goes out of scope, copies ds back to main */ + } schedule_butler_transport_work (); break; diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index c0468a63ca..17a6806c52 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -49,10 +49,11 @@ using namespace sigc; using namespace PBD; void -Session::request_input_change_handling () +Session::request_input_change_handling (boost::shared_ptr ds) { if (!(_state_of_the_state & (InitialConnecting|Deletion))) { Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0); + ev->diskstream = ds; queue_event (ev); } } @@ -196,9 +197,27 @@ Session::butler_transport_work () } if (post_transport_work & PostTransportInputChange) { - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->non_realtime_input_change (); + { + RCUWriter input_writer (diskstreams_input_pending); + boost::shared_ptr input_list = input_writer.get_copy (); + RCUWriter dswriter (diskstreams); + boost::shared_ptr ds = dswriter.get_copy(); + + for (DiskstreamList::iterator i = input_list->begin(); i != input_list->end(); ++i) { + + /* make the change */ + + (*i)->non_realtime_input_change (); + + /* now transfer it back onto the regular diskstreams list */ + + ds->push_back (*i); + } + + input_list->clear(); } + + diskstreams_input_pending.flush (); } if (post_transport_work & PostTransportSpeed) { -- cgit v1.2.3