summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-08-16 01:19:06 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-08-16 01:19:06 +0000
commit1ae094813858a2b8cf5b08569edcb9b15d910729 (patch)
tree6480b5875c393dab24ee410c8d661590bb3c4ffb /libs/ardour
parentc5619a0f981161b441da1216de1f9c2e26190768 (diff)
RCU-ification of AudioEngine port list, and DiskStreams. not well tested, but basically functional. better to get this in now rather than later.
git-svn-id: svn://localhost/ardour2/trunk@828 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h7
-rw-r--r--libs/ardour/ardour/audio_track.h4
-rw-r--r--libs/ardour/ardour/audioengine.h5
-rw-r--r--libs/ardour/ardour/diskstream.h21
-rw-r--r--libs/ardour/ardour/route.h5
-rw-r--r--libs/ardour/ardour/session.h18
-rw-r--r--libs/ardour/ardour/track.h6
-rw-r--r--libs/ardour/audio_diskstream.cc4
-rw-r--r--libs/ardour/audio_track.cc81
-rw-r--r--libs/ardour/audioengine.cc92
-rw-r--r--libs/ardour/auditioner.cc6
-rw-r--r--libs/ardour/diskstream.cc2
-rw-r--r--libs/ardour/route.cc3
-rw-r--r--libs/ardour/session.cc181
-rw-r--r--libs/ardour/session_butler.cc18
-rw-r--r--libs/ardour/session_export.cc5
-rw-r--r--libs/ardour/session_process.cc37
-rw-r--r--libs/ardour/session_state.cc10
-rw-r--r--libs/ardour/session_transport.cc83
-rw-r--r--libs/ardour/track.cc5
20 files changed, 308 insertions, 285 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 0cc2079d8e..18f8328cfd 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -59,12 +59,10 @@ class AudioDiskstream : public Diskstream
public:
AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
AudioDiskstream (Session &, const XMLNode&);
+ ~AudioDiskstream();
const PBD::ID& id() const { return _id; }
- // FIXME
- AudioDiskstream& ref() { _refcnt++; return *this; }
-
float playback_buffer_load() const;
float capture_buffer_load() const;
@@ -176,9 +174,6 @@ class AudioDiskstream : public Diskstream
private:
- /* use unref() to destroy a diskstream */
- ~AudioDiskstream();
-
struct ChannelInfo {
Sample *playback_wrap_buffer;
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 9892179085..33010dc880 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -46,7 +46,7 @@ class AudioTrack : public Track
int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
jack_nframes_t offset, bool can_record, bool rec_monitors_input);
- AudioDiskstream& audio_diskstream() const;
+ boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
int use_diskstream (string name);
int use_diskstream (const PBD::ID& id);
@@ -71,7 +71,7 @@ class AudioTrack : public Track
uint32_t n_process_buffers ();
private:
- int set_diskstream (AudioDiskstream&, void *);
+ int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *);
int deprecated_use_diskstream_connections ();
void set_state_part_two ();
void set_state_part_three ();
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index e7500fc7a2..00a0ce6b19 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -31,6 +31,8 @@
#include <glibmm/thread.h>
+#include <pbd/rcu.h>
+
#include <ardour/ardour.h>
#include <jack/jack.h>
#include <jack/transport.h>
@@ -189,7 +191,6 @@ class AudioEngine : public sigc::trackable
ARDOUR::Session *session;
jack_client_t *_jack;
std::string jack_client_name;
- Glib::Mutex port_lock;
Glib::Mutex _process_lock;
Glib::Mutex session_remove_lock;
Glib::Cond session_removed;
@@ -208,7 +209,7 @@ class AudioEngine : public sigc::trackable
int _usecs_per_cycle;
typedef std::set<Port*> Ports;
- Ports ports;
+ SerializedRCUManager<Ports> ports;
int process_callback (jack_nframes_t nframes);
void remove_all_ports ();
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index e0202a4fae..bcd418b452 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -34,6 +34,7 @@
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
#include <pbd/stateful.h>
+#include <pbd/destructible.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
@@ -43,7 +44,6 @@
#include <ardour/port.h>
#include <ardour/utils.h>
-
struct tm;
namespace ARDOUR {
@@ -54,7 +54,7 @@ class Session;
class Playlist;
class IO;
-class Diskstream : public Stateful, public sigc::trackable
+ class Diskstream : public Stateful, public sigc::trackable, public PBD::Destructible
{
public:
enum Flag {
@@ -63,16 +63,16 @@ class Diskstream : public Stateful, public sigc::trackable
Destructive = 0x4
};
+ Diskstream (Session &, const string& name, Flag f = Recordable);
+ Diskstream (Session &, const XMLNode&);
+ virtual ~Diskstream();
+
string name () const { return _name; }
virtual int set_name (string str);
ARDOUR::IO* io() const { return _io; }
void set_io (ARDOUR::IO& io);
- virtual Diskstream& ref() { _refcnt++; return *this; }
- void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
- uint32_t refcnt() const { return _refcnt; }
-
virtual float playback_buffer_load() const = 0;
virtual float capture_buffer_load() const = 0;
@@ -148,15 +148,11 @@ class Diskstream : public Stateful, public sigc::trackable
static sigc::signal<void> DiskOverrun;
static sigc::signal<void> DiskUnderrun;
- static sigc::signal<void,Diskstream*> DiskstreamCreated; // XXX use a ref with sigc2
static sigc::signal<void,list<Source*>*> DeleteSources;
protected:
friend class Session;
- Diskstream (Session &, const string& name, Flag f = Recordable);
- Diskstream (Session &, const XMLNode&);
-
/* the Session is the only point of access for these because they require
* that the Session is "inactive" while they are called.
*/
@@ -187,9 +183,6 @@ class Diskstream : public Stateful, public sigc::trackable
//private:
- /** Use unref() to destroy a diskstream */
- virtual ~Diskstream();
-
enum TransitionType {
CaptureStart = 0,
CaptureEnd
@@ -304,8 +297,6 @@ class Diskstream : public Stateful, public sigc::trackable
jack_nframes_t scrub_buffer_size;
jack_nframes_t scrub_offset;
- uint32_t _refcnt;
-
sigc::connection ports_created_c;
sigc::connection plmod_connection;
sigc::connection plstate_connection;
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index d1db818e40..ff7aa6184c 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -35,6 +35,7 @@
#include <pbd/undo.h>
#include <pbd/stateful.h>
#include <pbd/controllable.h>
+#include <pbd/destructible.h>
#include <ardour/ardour.h>
#include <ardour/io.h>
@@ -55,7 +56,7 @@ enum mute_type {
MAIN_OUTS = 0x8
};
-class Route : public IO
+ class Route : public IO, public PBD::Destructible
{
protected:
@@ -192,8 +193,6 @@ class Route : public IO
sigc::signal<void> active_changed;
sigc::signal<void,void*> meter_change;
- sigc::signal<void> GoingAway;
-
/* gui's call this for their own purposes. */
sigc::signal<void,std::string,void*> gui_changed;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index d067de4e68..3763ebe91e 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -270,8 +270,9 @@ class Session : public sigc::trackable, public Stateful
vector<Sample*>& get_silent_buffers (uint32_t howmany);
vector<Sample*>& get_send_buffers () { return _send_buffers; }
- Diskstream* diskstream_by_id (const PBD::ID& id);
- Diskstream* diskstream_by_name (string name);
+ void add_diskstream (boost::shared_ptr<Diskstream>);
+ boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id);
+ boost::shared_ptr<Diskstream> diskstream_by_name (string name);
bool have_captured() const { return _have_captured; }
@@ -281,9 +282,8 @@ class Session : public sigc::trackable, public Stateful
uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
uint32_t n_diskstreams() const;
- typedef list<Diskstream *> DiskstreamList;
-
- typedef std::list<boost::shared_ptr<Route> > RouteList;
+ typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
+ typedef std::list<boost::shared_ptr<Route> > RouteList;
boost::shared_ptr<RouteList> get_routes() const {
return routes.reader ();
@@ -346,7 +346,6 @@ class Session : public sigc::trackable, public Stateful
sigc::signal<void> HaltOnXrun;
sigc::signal<void,boost::shared_ptr<Route> > RouteAdded;
- sigc::signal<void,Diskstream*> DiskstreamAdded; // FIXME: make a shared_ptr
void request_roll ();
void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
@@ -1509,10 +1508,9 @@ class Session : public sigc::trackable, public Stateful
/* disk-streams */
- DiskstreamList diskstreams;
- mutable Glib::RWLock diskstream_lock;
+ SerializedRCUManager<DiskstreamList> diskstreams;
+
uint32_t dstream_buffer_size;
- void add_diskstream (Diskstream*);
int load_diskstreams (const XMLNode&);
/* routes stuff */
@@ -1580,7 +1578,7 @@ class Session : public sigc::trackable, public Stateful
Playlist *XMLPlaylistFactory (const XMLNode&);
void playlist_length_changed (Playlist *);
- void diskstream_playlist_changed (Diskstream *);
+ void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
/* NAMED SELECTIONS */
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 4e2af5c80e..ec444e78dc 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -19,6 +19,8 @@
#ifndef __ardour_track_h__
#define __ardour_track_h__
+#include <boost/shared_ptr.hpp>
+
#include <ardour/route.h>
namespace ARDOUR {
@@ -50,7 +52,7 @@ class Track : public Route
virtual bool can_record();
- Diskstream& diskstream() const { return *_diskstream; }
+ boost::shared_ptr<Diskstream> diskstream() const { return _diskstream; }
virtual int use_diskstream (string name) = 0;
virtual int use_diskstream (const PBD::ID& id) = 0;
@@ -100,7 +102,7 @@ class Track : public Route
virtual uint32_t n_process_buffers () = 0;
- Diskstream *_diskstream;
+ boost::shared_ptr<Diskstream> _diskstream;
MeterPoint _saved_meter_point;
TrackMode _mode;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index d3e64104a0..baefeff377 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -71,8 +71,6 @@ AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream:
use_new_playlist ();
in_set_state = false;
-
- DiskstreamCreated (this); /* EMIT SIGNAL */
}
AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
@@ -92,8 +90,6 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
if (destructive()) {
use_destructive_playlist ();
}
-
- DiskstreamCreated (this); /* EMIT SIGNAL */
}
void
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 2f33012546..98a2262f86 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -55,9 +55,10 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
}
- AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags);
-
- set_diskstream (*ds, this);
+ boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags));
+ _session.add_diskstream (ds);
+
+ set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
}
AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
@@ -73,18 +74,18 @@ AudioTrack::~AudioTrack ()
int
AudioTrack::deprecated_use_diskstream_connections ()
{
- AudioDiskstream& diskstream = audio_diskstream();
+ boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
- if (diskstream.deprecated_io_node == 0) {
+ if (diskstream->deprecated_io_node == 0) {
return 0;
}
const XMLProperty* prop;
- XMLNode& node (*diskstream.deprecated_io_node);
+ XMLNode& node (*diskstream->deprecated_io_node);
/* don't do this more than once. */
- diskstream.deprecated_io_node = 0;
+ diskstream->deprecated_io_node = 0;
set_input_minimum (-1);
set_input_maximum (-1);
@@ -125,17 +126,13 @@ AudioTrack::deprecated_use_diskstream_connections ()
}
int
-AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
+AudioTrack::set_diskstream (boost::shared_ptr<AudioDiskstream> ds, void *src)
{
- if (_diskstream) {
- _diskstream->unref();
- }
-
- _diskstream = &ds.ref();
+ _diskstream = ds;
_diskstream->set_io (*this);
_diskstream->set_destructive (_mode == Destructive);
- if (audio_diskstream().deprecated_io_node) {
+ if (audio_diskstream()->deprecated_io_node) {
if (!connecting_legal) {
ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
@@ -158,33 +155,33 @@ AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
int
AudioTrack::use_diskstream (string name)
{
- AudioDiskstream *dstream;
+ boost::shared_ptr<AudioDiskstream> dstream;
- if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_name (name))) == 0) {
- error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
+ if ((dstream = boost::dynamic_pointer_cast<AudioDiskstream>(_session.diskstream_by_name (name))) == 0) {
+ error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
return -1;
}
- return set_diskstream (*dstream, this);
+ return set_diskstream (dstream, this);
}
int
AudioTrack::use_diskstream (const PBD::ID& id)
{
- AudioDiskstream *dstream;
+ boost::shared_ptr<AudioDiskstream> dstream;
- if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_id (id))) == 0) {
+ if ((dstream = boost::dynamic_pointer_cast<AudioDiskstream> (_session.diskstream_by_id (id))) == 0) {
error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg;
return -1;
}
- return set_diskstream (*dstream, this);
+ return set_diskstream (dstream, this);
}
-AudioDiskstream&
+boost::shared_ptr<AudioDiskstream>
AudioTrack::audio_diskstream() const
{
- return *dynamic_cast<AudioDiskstream*>(_diskstream);
+ return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream);
}
int
@@ -434,7 +431,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
return 0;
}
- audio_diskstream().check_record_status (start_frame, nframes, can_record);
+ audio_diskstream()->check_record_status (start_frame, nframes, can_record);
bool send_silence;
@@ -501,7 +498,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
Sample* b;
Sample* tmpb;
jack_nframes_t transport_frame;
- AudioDiskstream& diskstream = audio_diskstream();
+ boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
{
Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
@@ -528,13 +525,13 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
playback distance to zero, thus causing diskstream::commit
to do nothing.
*/
- return diskstream.process (transport_frame, 0, 0, can_record, rec_monitors_input);
+ return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
}
_silent = false;
apply_gain_automation = false;
- if ((dret = diskstream.process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
+ if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
silence (nframes, offset);
@@ -547,7 +544,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
just_meter_input (start_frame, end_frame, nframes, offset);
}
- if (diskstream.record_enabled() && !can_record && !_session.get_auto_input()) {
+ if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
/* not actually recording, but we want to hear the input material anyway,
at least potentially (depending on monitoring options)
@@ -555,7 +552,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
passthru (start_frame, end_frame, nframes, offset, 0, true);
- } else if ((b = diskstream.playback_buffer(0)) != 0) {
+ } else if ((b = diskstream->playback_buffer(0)) != 0) {
/*
XXX is it true that the earlier test on n_outputs()
@@ -577,8 +574,8 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
for (i = 0, n = 1; i < limit; ++i, ++n) {
memcpy (bufs[i], b, sizeof (Sample) * nframes);
- if (n < diskstream.n_channels()) {
- tmpb = diskstream.playback_buffer(n);
+ if (n < diskstream->n_channels()) {
+ tmpb = diskstream->playback_buffer(n);
if (tmpb!=0) {
b = tmpb;
}
@@ -587,7 +584,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
/* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
- if (!diskstream.record_enabled() && _session.transport_rolling()) {
+ if (!diskstream->record_enabled() && _session.transport_rolling()) {
Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
if (am.locked() && gain_automation_playback()) {
@@ -623,7 +620,7 @@ AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jac
silence (nframes, offset);
- return audio_diskstream().process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
+ return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
}
int
@@ -637,12 +634,12 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes
gain_t this_gain = _gain;
vector<Sample*>::iterator bi;
Sample * b;
- AudioDiskstream& diskstream = audio_diskstream();
+ boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
Glib::RWLock::ReaderLock rlock (redirect_lock);
// FIXME
- AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream.playlist());
+ AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream->playlist());
assert(apl);
if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
@@ -654,7 +651,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes
b = buffers[0];
++bi;
for (; bi != buffers.end(); ++bi, ++n) {
- if (n < diskstream.n_channels()) {
+ if (n < diskstream->n_channels()) {
if (apl->read ((*bi), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
return -1;
}
@@ -751,9 +748,9 @@ AudioTrack::freeze (InterThreadInfo& itt)
string dir;
AudioRegion* region;
string region_name;
- AudioDiskstream& diskstream = audio_diskstream();
+ boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
- if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(diskstream.playlist())) == 0) {
+ if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(diskstream->playlist())) == 0) {
return;
}
@@ -821,13 +818,13 @@ AudioTrack::freeze (InterThreadInfo& itt)
(AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
false);
- new_playlist->set_orig_diskstream_id (diskstream.id());
+ new_playlist->set_orig_diskstream_id (diskstream->id());
new_playlist->add_region (*region, 0);
new_playlist->set_frozen (true);
region->set_locked (true);
- diskstream.use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
- diskstream.set_record_enabled (false);
+ diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
+ diskstream->set_record_enabled (false);
_freeze_record.state = Frozen;
FreezeChange(); /* EMIT SIGNAL */
@@ -837,7 +834,7 @@ void
AudioTrack::unfreeze ()
{
if (_freeze_record.playlist) {
- audio_diskstream().use_playlist (_freeze_record.playlist);
+ audio_diskstream()->use_playlist (_freeze_record.playlist);
if (_freeze_record.have_mementos) {
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 982a7c5971..4a4659d1df 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -47,6 +47,7 @@ jack_nframes_t Port::_short_over_length = 2;
jack_nframes_t Port::_long_over_length = 10;
AudioEngine::AudioEngine (string client_name)
+ : ports (new Ports)
{
session = 0;
session_remove_pending = false;
@@ -270,7 +271,10 @@ AudioEngine::process_callback (jack_nframes_t nframes)
}
if (last_monitor_check + monitor_check_interval < next_processed_frames) {
- for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
+
+ boost::shared_ptr<Ports> p = ports.reader();
+
+ for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
Port *port = (*i);
bool x;
@@ -329,7 +333,9 @@ AudioEngine::jack_bufsize_callback (jack_nframes_t nframes)
_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
last_monitor_check = 0;
- for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
+ boost::shared_ptr<Ports> p = ports.reader();
+
+ for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
(*i)->reset();
}
@@ -400,15 +406,19 @@ AudioEngine::register_input_port (DataType type, const string& portname)
}
}
- jack_port_t *p = jack_port_register (_jack, portname.c_str(),
- type.to_jack_type(), JackPortIsInput, 0);
+ jack_port_t *p = jack_port_register (_jack, portname.c_str(), type.to_jack_type(), JackPortIsInput, 0);
if (p) {
Port *newport;
+
if ((newport = new Port (p)) != 0) {
- ports.insert (ports.begin(), newport);
+ RCUWriter<Ports> writer (ports);
+ boost::shared_ptr<Ports> ps = writer.get_copy ();
+ ps->insert (ps->begin(), newport);
+ /* writer goes out of scope, forces update */
}
+
return newport;
} else {
@@ -436,8 +446,19 @@ AudioEngine::register_output_port (DataType type, const string& portname)
if ((p = jack_port_register (_jack, portname.c_str(),
type.to_jack_type(), JackPortIsOutput, 0)) != 0) {
- Port *newport = new Port (p);
- ports.insert (ports.begin(), newport);
+
+ Port *newport = 0;
+
+ {
+ RCUWriter<Ports> writer (ports);
+ boost::shared_ptr<Ports> ps = writer.get_copy ();
+
+ newport = new Port (p);
+ ps->insert (ps->begin(), newport);
+
+ /* writer goes out of scope, forces update */
+ }
+
return newport;
} else {
@@ -465,12 +486,20 @@ AudioEngine::unregister_port (Port *port)
int ret = jack_port_unregister (_jack, port->_port);
if (ret == 0) {
-
- for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
- if ((*i) == port) {
- ports.erase (i);
- break;
+
+ {
+
+ RCUWriter<Ports> writer (ports);
+ boost::shared_ptr<Ports> ps = writer.get_copy ();
+
+ for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
+ if ((*i) == port) {
+ ps->erase (i);
+ break;
+ }
}
+
+ /* writer goes out of scope, forces update */
}
remove_connections_for (port);
@@ -613,7 +642,9 @@ AudioEngine::get_port_by_name (const string& portname, bool keep)
/* check to see if we have a Port for this name already */
- for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
+ boost::shared_ptr<Ports> pr = ports.reader();
+
+ for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) {
if (portname == (*i)->name()) {
return (*i);
}
@@ -623,11 +654,20 @@ AudioEngine::get_port_by_name (const string& portname, bool keep)
if ((p = jack_port_by_name (_jack, portname.c_str())) != 0) {
Port *newport = new Port (p);
- if (keep && newport->is_mine (_jack)) {
- ports.insert (newport);
+
+ {
+ if (keep && newport->is_mine (_jack)) {
+ RCUWriter<Ports> writer (ports);
+ boost::shared_ptr<Ports> ps = writer.get_copy ();
+ ps->insert (newport);
+ /* writer goes out of scope, forces update */
+ }
}
+
return newport;
+
} else {
+
return 0;
}
}
@@ -827,12 +867,19 @@ AudioEngine::remove_all_ports ()
/* process lock MUST be held */
if (_jack) {
- for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
+ boost::shared_ptr<Ports> p = ports.reader();
+
+ for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
jack_port_unregister (_jack, (*i)->_port);
}
}
- ports.clear ();
+ {
+ RCUWriter<Ports> writer (ports);
+ boost::shared_ptr<Ports> ps = writer.get_copy ();
+ ps->clear ();
+ }
+
port_connections.clear ();
}
@@ -932,7 +979,7 @@ AudioEngine::reconnect_to_jack ()
if (_jack) {
disconnect_from_jack ();
/* XXX give jackd a chance */
- Glib::usleep (250000);
+ Glib::usleep (250000);
}
if (connect_to_jack (jack_client_name)) {
@@ -942,7 +989,9 @@ AudioEngine::reconnect_to_jack ()
Ports::iterator i;
- for (i = ports.begin(); i != ports.end(); ++i) {
+ boost::shared_ptr<Ports> p = ports.reader ();
+
+ for (i = p->begin(); i != p->end(); ++i) {
/* XXX hack hack hack */
@@ -964,8 +1013,9 @@ AudioEngine::reconnect_to_jack ()
}
}
- if (i != ports.end()) {
- for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
+ if (i != p->end()) {
+ /* failed */
+ for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
jack_port_unregister (_jack, (*i)->_port);
}
return -1;
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index e48f103b9f..dc08979458 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -49,7 +49,7 @@ Auditioner::Auditioner (Session& s)
}
if (right.length()) {
- audio_diskstream().add_channel();
+ audio_diskstream()->add_channel();
add_output_port (right, this, DataType::AUDIO);
}
@@ -117,11 +117,11 @@ Auditioner::audition_region (AudioRegion& region)
_diskstream->playlist()->add_region (*the_region, 0, 1, false);
while (_diskstream->n_channels() < the_region->n_channels()) {
- audio_diskstream().add_channel ();
+ audio_diskstream()->add_channel ();
}
while (_diskstream->n_channels() > the_region->n_channels()) {
- audio_diskstream().remove_channel ();
+ audio_diskstream()->remove_channel ();
}
/* force a panner reset now that we have all channels */
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index b2d481077f..151ff5bd3e 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -63,7 +63,6 @@ using namespace PBD;
*/
jack_nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256;
-sigc::signal<void,Diskstream*> Diskstream::DiskstreamCreated;
sigc::signal<void,list<Source*>*> Diskstream::DeleteSources;
sigc::signal<void> Diskstream::DiskOverrun;
sigc::signal<void> Diskstream::DiskUnderrun;
@@ -86,7 +85,6 @@ Diskstream::Diskstream (Session& sess, const XMLNode& node)
void
Diskstream::init (Flag f)
{
- _refcnt = 0;
_flags = f;
_io = 0;
_alignment_style = ExistingMaterial;
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index b47981a47e..02c62eefa1 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -111,7 +111,8 @@ Route::init ()
Route::~Route ()
{
- GoingAway (); /* EMIT SIGNAL */
+ cerr << "deleting route " << _name << endl;
+
clear_redirects (this);
if (_control_outs) {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 48f7fc30e9..378d4763bc 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -256,6 +256,7 @@ Session::Session (AudioEngine &eng,
_midi_port (default_midi_port),
pending_events (2048),
midi_requests (128), // the size of this should match the midi request pool size
+ diskstreams (new DiskstreamList),
routes (new RouteList),
auditioner ((Auditioner*) 0),
_click_io ((IO*) 0),
@@ -306,6 +307,7 @@ Session::Session (AudioEngine &eng,
_midi_port (default_midi_port),
pending_events (2048),
midi_requests (16),
+ diskstreams (new DiskstreamList),
routes (new RouteList),
main_outs (0)
@@ -439,18 +441,45 @@ Session::~Session ()
}
#ifdef TRACK_DESTRUCTION
- cerr << "delete diskstreams\n";
+ cerr << "delete routes\n";
#endif /* TRACK_DESTRUCTION */
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
- DiskstreamList::iterator tmp;
-
- tmp = i;
- ++tmp;
+ {
+ RCUWriter<RouteList> writer (routes);
+ boost::shared_ptr<RouteList> r = writer.get_copy ();
+ for (RouteList::iterator i = r->begin(); i != r->end(); ) {
+ RouteList::iterator tmp;
+ tmp = i;
+ ++tmp;
+ cerr << "BEFORE: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
+ (*i)->drop_references ();
+ cerr << "AFTER: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
+ i = tmp;
+ }
+ r->clear ();
+ /* writer goes out of scope and updates master */
+ }
- delete *i;
+ routes.flush ();
- i = tmp;
- }
+#ifdef TRACK_DESTRUCTION
+ cerr << "delete diskstreams\n";
+#endif /* TRACK_DESTRUCTION */
+ {
+ RCUWriter<DiskstreamList> dwriter (diskstreams);
+ boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
+ DiskstreamList::iterator tmp;
+
+ tmp = i;
+ ++tmp;
+
+ (*i)->drop_references ();
+
+ i = tmp;
+ }
+ dsl->clear ();
+ }
+ diskstreams.flush ();
#ifdef TRACK_DESTRUCTION
cerr << "delete audio sources\n";
@@ -859,7 +888,7 @@ Session::playlist_length_changed (Playlist* pl)
}
void
-Session::diskstream_playlist_changed (Diskstream* dstream)
+Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
{
Playlist *playlist;
@@ -933,13 +962,10 @@ Session::set_auto_input (bool yn)
if (Config->get_use_hardware_monitoring() && transport_rolling()) {
/* auto-input only makes a difference if we're rolling */
+
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- /* Even though this can called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (!auto_input);
@@ -956,16 +982,19 @@ void
Session::reset_input_monitor_state ()
{
if (transport_rolling()) {
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
}
}
} else {
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (Config->get_use_hardware_monitoring());
@@ -1237,13 +1266,8 @@ Session::enable_record ()
send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
if (Config->get_use_hardware_monitoring() && auto_input) {
- /* Even though this can be called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
-
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
(*i)->monitor_input (true);
}
@@ -1272,13 +1296,9 @@ Session::disable_record (bool rt_context, bool force)
send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
if (Config->get_use_hardware_monitoring() && auto_input) {
- /* Even though this can be called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
(*i)->monitor_input (false);
}
@@ -1299,13 +1319,9 @@ Session::step_back_from_record ()
g_atomic_int_set (&_record_status, Enabled);
if (Config->get_use_hardware_monitoring()) {
- /* Even though this can be called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (auto_input && (*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false);
@@ -1428,7 +1444,6 @@ Session::set_block_size (jack_nframes_t nframes)
*/
{
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
vector<Sample*>::iterator i;
uint32_t np;
@@ -1475,7 +1490,8 @@ Session::set_block_size (jack_nframes_t nframes)
(*i)->set_block_size (nframes);
}
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->set_block_size (nframes);
}
@@ -1863,7 +1879,7 @@ Session::new_audio_route (int input_channels, int output_channels)
}
void
-Session::add_route (shared_ptr<Route> route)
+Session::add_route (boost::shared_ptr<Route> route)
{
{
RCUWriter<RouteList> writer (routes);
@@ -1892,22 +1908,17 @@ Session::add_route (shared_ptr<Route> route)
}
void
-Session::add_diskstream (Diskstream* dstream)
+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();
{
- Glib::RWLock::WriterLock lm (diskstream_lock);
- diskstreams.push_back (dstream);
+ RCUWriter<DiskstreamList> writer (diskstreams);
+ boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
+ ds->push_back (dstream);
}
- /* take a reference to the diskstream, preventing it from
- ever being deleted until the session itself goes away,
- or chooses to remove it for its own purposes.
- */
-
- dstream->ref();
dstream->set_block_size (current_block_size);
dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
@@ -1918,8 +1929,6 @@ Session::add_diskstream (Diskstream* dstream)
set_dirty();
save_state (_current_snapshot_name);
-
- DiskstreamAdded (dstream); /* EMIT SIGNAL */
}
void
@@ -1958,20 +1967,19 @@ Session::remove_route (shared_ptr<Route> route)
// FIXME: audio specific
AudioTrack* at;
- AudioDiskstream* ds = 0;
+ boost::shared_ptr<AudioDiskstream> ds;
if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
- ds = &at->audio_diskstream();
+ ds = at->audio_diskstream();
}
if (ds) {
{
- Glib::RWLock::WriterLock lm (diskstream_lock);
- diskstreams.remove (ds);
+ RCUWriter<DiskstreamList> dsl (diskstreams);
+ boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
+ d->remove (ds);
}
-
- ds->unref ();
}
find_current_end ();
@@ -1983,7 +1991,9 @@ Session::remove_route (shared_ptr<Route> route)
save_state (_current_snapshot_name);
- /* all shared ptrs to route should go out of scope here */
+ /* try to cause everyone to drop their references */
+
+ route->drop_references ();
}
void
@@ -2271,11 +2281,9 @@ Session::get_maximum_extent () const
jack_nframes_t max = 0;
jack_nframes_t me;
- /* Don't take the diskstream lock. Caller must have other ways to
- ensure atomicity.
- */
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
Playlist* pl = (*i)->playlist();
if ((me = pl->get_maximum_extent()) > max) {
max = me;
@@ -2285,32 +2293,32 @@ Session::get_maximum_extent () const
return max;
}
-Diskstream *
+boost::shared_ptr<Diskstream>
Session::diskstream_by_name (string name)
{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->name() == name) {
- return* i;
+ return *i;
}
}
- return 0;
+ return boost::shared_ptr<Diskstream>((Diskstream*) 0);
}
-Diskstream *
+boost::shared_ptr<Diskstream>
Session::diskstream_by_id (const PBD::ID& id)
{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->id() == id) {
return *i;
}
}
- return 0;
+ return boost::shared_ptr<Diskstream>((Diskstream*) 0);
}
/* AudioRegion management */
@@ -2621,10 +2629,10 @@ int
Session::remove_last_capture ()
{
list<Region*> r;
-
- Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
list<Region*>& l = (*i)->last_capture_regions();
if (!l.empty()) {
@@ -3185,10 +3193,11 @@ Session::set_all_mute (bool yn)
uint32_t
Session::n_diskstreams () const
{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
uint32_t n = 0;
- for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
n++;
}
@@ -3207,15 +3216,15 @@ Session::graph_reordered ()
return;
}
- Glib::RWLock::ReaderLock lm2 (diskstream_lock);
-
resort_routes ();
/* force all diskstreams to update their capture offset values to
reflect any changes in latencies within the graph.
*/
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->set_capture_offset ();
}
}
@@ -3494,11 +3503,9 @@ Session::remove_named_selection (NamedSelection* named_selection)
void
Session::reset_native_file_format ()
{
- // jlc - WHY take routelock?
- //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
- Glib::RWLock::ReaderLock lm2 (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->reset_write_sources (false);
}
}
@@ -3608,7 +3615,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
/* call tree *MUST* hold route_lock */
- if ((playlist = track.diskstream().playlist()) == 0) {
+ if ((playlist = track.diskstream()->playlist()) == 0) {
goto out;
}
@@ -3618,7 +3625,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
goto out;
}
- nchans = track.audio_diskstream().n_channels();
+ nchans = track.audio_diskstream()->n_channels();
dir = discover_best_sound_dir ();
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 6509a783bb..5d691a7425 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -248,11 +248,11 @@ Session::butler_thread_work ()
gettimeofday (&begin, 0);
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
- for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
+ for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
- Diskstream* const ds = *i;
+ boost::shared_ptr<Diskstream> ds = *i;
switch (ds->do_refill ()) {
case 0:
@@ -271,7 +271,7 @@ Session::butler_thread_work ()
}
- if (i != diskstreams.end()) {
+ if (i != dsl->end()) {
/* we didn't get to all the streams */
disk_work_outstanding = true;
}
@@ -293,7 +293,7 @@ Session::butler_thread_work ()
compute_io = true;
gettimeofday (&begin, 0);
- for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
+ for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
switch ((*i)->do_flush (Session::ButlerContext)) {
@@ -322,7 +322,7 @@ Session::butler_thread_work ()
request_stop ();
}
- if (i != diskstreams.end()) {
+ if (i != dsl->end()) {
/* we didn't get to all the streams */
disk_work_outstanding = true;
}
@@ -349,7 +349,7 @@ Session::butler_thread_work ()
Glib::Mutex::Lock lm (butler_request_lock);
if (butler_should_run && (disk_work_outstanding || transport_work_requested())) {
-// for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+// for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
// cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
// }
@@ -388,8 +388,8 @@ Session::overwrite_some_buffers (Diskstream* ds)
} else {
- Glib::RWLock::ReaderLock dm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->set_pending_overwrite (true);
}
}
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index b39c4f2218..98653314b0 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -495,8 +495,9 @@ Session::prepare_to_export (AudioExportSpecification& spec)
/* get everyone to the right position */
{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)-> seek (spec.start_frame, true)) {
error << string_compose (_("%1: cannot seek to %2 for export"),
(*i)->name(), spec.start_frame)
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 88b111a1fb..68ad11cf42 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -66,7 +66,8 @@ Session::process (jack_nframes_t nframes)
void
Session::prepare_diskstreams ()
{
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->prepare ();
}
}
@@ -141,7 +142,8 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
call path, so make sure we release any outstanding locks here before we return failure.
*/
- for (DiskstreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
(*ids)->recover ();
}
@@ -181,7 +183,8 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
call path, so make sure we release any outstanding locks here before we return failure.
*/
- for (DiskstreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
(*ids)->recover ();
}
@@ -200,7 +203,8 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
float pworst = 1.0f;
float cworst = 1.0f;
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->hidden()) {
continue;
@@ -284,12 +288,10 @@ Session::process_with_events (jack_nframes_t nframes)
end_frame = _transport_frame + nframes;
{
- Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
-
Event* this_event;
Events::iterator the_next_one;
- if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
+ if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
no_roll (nframes, 0);
return;
}
@@ -560,17 +562,18 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
if (slave_state == Waiting) {
// cerr << "waiting at " << slave_transport_frame << endl;
- Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
-
- if (dsm.locked() && slave_transport_frame >= slave_wait_end) {
+
+ if (slave_transport_frame >= slave_wait_end) {
// cerr << "\tstart at " << _transport_frame << endl;
slave_state = Running;
bool ok = true;
jack_nframes_t frame_delta = slave_transport_frame - _transport_frame;
+
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->can_internal_playback_seek (frame_delta)) {
ok = false;
break;
@@ -578,7 +581,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
}
if (ok) {
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->internal_playback_seek (frame_delta);
}
_transport_frame += frame_delta;
@@ -682,12 +685,6 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
bool need_butler;
- Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
- if (!dsm.locked()) {
- goto noroll;
- }
-
-
prepare_diskstreams ();
silent_process_routes (nframes, offset);
commit_diskstreams (nframes, need_butler);
@@ -733,9 +730,7 @@ Session::process_without_events (jack_nframes_t nframes)
long frames_moved;
{
- Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
-
- if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
+ if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
no_roll (nframes, 0);
return;
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 5a75c04b3f..6770428c65 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -264,7 +264,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
- AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
@@ -626,11 +625,10 @@ Session::load_diskstreams (const XMLNode& node)
for (citer = clist.begin(); citer != clist.end(); ++citer) {
- AudioDiskstream* dstream;
try {
- dstream = new AudioDiskstream (*this, **citer);
- /* added automatically by AudioDiskstreamCreated handler */
+ boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
+ add_diskstream (dstream);
}
catch (failed_constructor& err) {
@@ -1388,8 +1386,8 @@ Session::state(bool full_state)
child = node->add_child ("DiskStreams");
{
- Glib::RWLock::ReaderLock dl (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
child->add_child_nocopy ((*i)->get_state());
}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 7c2b4f1c6f..8e0522c19d 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -192,8 +192,8 @@ Session::realtime_stop (bool abort)
void
Session::butler_transport_work ()
{
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
boost::shared_ptr<RouteList> r = routes.reader ();
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
if (post_transport_work & PostTransportCurveRealloc) {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
@@ -202,7 +202,7 @@ Session::butler_transport_work ()
}
if (post_transport_work & PostTransportInputChange) {
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->non_realtime_input_change ();
}
}
@@ -218,7 +218,7 @@ Session::butler_transport_work ()
cumulative_rf_motion = 0;
reset_rf_scale (0);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
(*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@@ -248,9 +248,9 @@ Session::butler_transport_work ()
void
Session::non_realtime_set_speed ()
{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->non_realtime_set_speed ();
}
}
@@ -258,9 +258,9 @@ Session::non_realtime_set_speed ()
void
Session::non_realtime_overwrite ()
{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->pending_overwrite) {
(*i)->overwrite_existing_buffers ();
}
@@ -276,7 +276,9 @@ Session::non_realtime_stop (bool abort)
did_record = false;
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->get_captured_frames () != 0) {
did_record = true;
break;
@@ -331,7 +333,7 @@ Session::non_realtime_stop (bool abort)
_have_captured = true;
}
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->transport_stopped (*now, xnow, abort);
}
@@ -370,7 +372,7 @@ Session::non_realtime_stop (bool abort)
}
#endif
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
(*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@@ -497,7 +499,8 @@ Session::set_auto_loop (bool yn)
if (seamless_loop) {
// set all diskstreams to use internal looping
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_loop (loc);
}
@@ -505,7 +508,8 @@ Session::set_auto_loop (bool yn)
}
else {
// set all diskstreams to NOT use internal looping
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_loop (0);
}
@@ -535,7 +539,8 @@ Session::set_auto_loop (bool yn)
clear_events (Event::AutoLoop);
// set all diskstreams to NOT use internal looping
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_loop (0);
}
@@ -648,12 +653,10 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
if (with_roll) {
/* switch from input if we're going to roll */
if (Config->get_use_hardware_monitoring()) {
- /* Even though this is called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (!auto_input);
@@ -663,12 +666,9 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
} else {
/* otherwise we're going to stop, so do the opposite */
if (Config->get_use_hardware_monitoring()) {
- /* Even though this is called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (true);
@@ -707,12 +707,9 @@ Session::set_transport_speed (float speed, bool abort)
if (Config->get_use_hardware_monitoring())
{
- /* Even though this is called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (true);
@@ -733,12 +730,10 @@ Session::set_transport_speed (float speed, bool abort)
}
if (Config->get_use_hardware_monitoring()) {
- /* Even though this is called from RT context we are using
- a non-tentative rwlock here, because the action must occur.
- The rarity and short potential lock duration makes this "OK"
- */
- Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (auto_input && (*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false);
@@ -789,7 +784,8 @@ Session::set_transport_speed (float speed, bool abort)
_last_transport_speed = _transport_speed;
_transport_speed = speed;
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
}
@@ -879,7 +875,8 @@ Session::actually_start_transport ()
transport_sub_state |= PendingDeclickIn;
_transport_speed = 1.0;
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->realtime_set_speed ((*i)->speed(), true);
}
@@ -1009,7 +1006,8 @@ Session::set_slave_source (SlaveSource src, jack_nframes_t frame)
_slave_type = src;
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
non_rt_required = true;
@@ -1200,7 +1198,6 @@ Session::update_latency_compensation (bool with_stop, bool abort)
return;
}
- Glib::RWLock::ReaderLock lm2 (diskstream_lock);
_worst_track_latency = 0;
boost::shared_ptr<RouteList> r = routes.reader ();
@@ -1238,7 +1235,9 @@ Session::update_latency_compensation (bool with_stop, bool abort)
/* reflect any changes in latencies into capture offsets
*/
- for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->set_capture_offset ();
}
}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 58d8c1b306..c8633d9e52 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -41,7 +41,6 @@ using namespace PBD;
Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
: Route (sess, name, 1, -1, -1, -1, flag, default_type)
- , _diskstream (0)
, _rec_enable_control (*this)
{
_declickable = true;
@@ -52,7 +51,6 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
Track::Track (Session& sess, const XMLNode& node, DataType default_type)
: Route (sess, "to be renamed", 0, 0, -1, -1, Route::Flag(0), default_type)
- , _diskstream (0)
, _rec_enable_control (*this)
{
_freeze_record.state = NoFreeze;
@@ -62,9 +60,6 @@ Track::Track (Session& sess, const XMLNode& node, DataType default_type)
Track::~Track ()
{
- if (_diskstream) {
- _diskstream->unref();
- }
}
void