summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-03-16 04:09:03 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-03-16 04:09:03 +0000
commitbca0450c188cdac82fbc74d05b5d72aff9115646 (patch)
tree688870950203e270b1dbc9baf975daa4c6d0d56c
parent0b7a7cba788c20d9554ab8aa5b38bacf16e72ab6 (diff)
possible fix for crash while adding new tracks
git-svn-id: svn://localhost/ardour2/trunk@1603 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/audio_diskstream.h10
-rw-r--r--libs/ardour/ardour/diskstream.h4
-rw-r--r--libs/ardour/ardour/session.h6
-rw-r--r--libs/ardour/audio_diskstream.cc20
-rw-r--r--libs/ardour/audio_track.cc1
-rw-r--r--libs/ardour/diskstream.cc5
-rw-r--r--libs/ardour/session.cc20
-rw-r--r--libs/ardour/session_events.cc12
-rw-r--r--libs/ardour/session_transport.cc25
9 files changed, 68 insertions, 35 deletions
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<boost::shared_ptr<AudioFileSource> > capturing_sources;
typedef vector<ChannelInfo> 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 <sigc++/signal.h>
+#include <boost/enable_shared_from_this.hpp>
#include <cmath>
#include <string>
@@ -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<ARDOUR::Diskstream>
{
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> region;
+ boost::shared_ptr<Region> region;
+ boost::shared_ptr<Diskstream> diskstream;
list<AudioRange> audio_range;
list<MusicRange> 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<ARDOUR::Diskstream>);
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
bool transport_locked () const;
@@ -1424,6 +1425,7 @@ class Session : public PBD::StatefulDestructible
/* disk-streams */
SerializedRCUManager<DiskstreamList> diskstreams;
+ SerializedRCUManager<DiskstreamList> 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 <pbd/xml++.h>
#include <pbd/memento_command.h>
#include <pbd/enumwriter.h>
+#include <pbd/stacktrace.h>
#include <ardour/ardour.h>
#include <ardour/audioengine.h>
@@ -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<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags));
+
_session.add_diskstream (ds);
set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (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<Diskstream> 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<DiskstreamList> writer (diskstreams);
boost::shared_ptr<DiskstreamList> 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<DiskstreamList> 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<DiskstreamList> writer (diskstreams);
+ boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
+ ds->remove (ev->diskstream);
+ /* writer goes out of scope, copies ds back to main */
+ }
+ {
+ RCUWriter<DiskstreamList> writer (diskstreams_input_pending);
+ boost::shared_ptr<DiskstreamList> 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<Diskstream> 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<DiskstreamList> input_writer (diskstreams_input_pending);
+ boost::shared_ptr<DiskstreamList> input_list = input_writer.get_copy ();
+ RCUWriter<DiskstreamList> dswriter (diskstreams);
+ boost::shared_ptr<DiskstreamList> 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) {