13
0

possible fix for crash while adding new tracks

git-svn-id: svn://localhost/ardour2/trunk@1603 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-03-16 04:09:03 +00:00
parent 0b7a7cba78
commit bca0450c18
9 changed files with 68 additions and 35 deletions

View File

@ -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

View File

@ -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 ... */

View File

@ -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&);

View File

@ -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) {

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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 ();

View File

@ -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;

View File

@ -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) {