summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-01-03 18:08:11 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-01-03 18:08:11 +0000
commitca81401b14782b5d13905732778e6bf9b5f5f2ae (patch)
treebf4c346b8cdb8bbdf86e8ba0f0efc80c87d4adc3
parentb5f497c0c98501cf6a9deff7593e286613b7dc0c (diff)
massive changes to clean up what happens during session destruction when an exception is thrown
git-svn-id: svn://localhost/ardour2/trunk@1261 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour_ui.cc20
-rw-r--r--gtk2_ardour/ardour_ui.h2
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc2
-rw-r--r--gtk2_ardour/main.cc11
-rw-r--r--libs/ardour/ardour/audio_diskstream.h54
-rw-r--r--libs/ardour/ardour/audioengine.h3
-rw-r--r--libs/ardour/ardour/io.h4
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/audio_diskstream.cc162
-rw-r--r--libs/ardour/audioengine.cc47
-rw-r--r--libs/ardour/io.cc41
-rw-r--r--libs/ardour/session.cc12
-rw-r--r--libs/ardour/session_state.cc12
13 files changed, 227 insertions, 144 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 4875b8db89..9692c89218 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -1262,14 +1262,6 @@ ARDOUR_UI::do_engine_start ()
engine->start();
}
- catch (AudioEngine::PortRegistrationFailure& err) {
- engine->stop ();
- error << _("Unable to create all required ports")
- << endmsg;
- unload_session ();
- return -1;
- }
-
catch (...) {
engine->stop ();
error << _("Unable to start the session running")
@@ -1588,7 +1580,7 @@ ARDOUR_UI::save_template ()
}
void
-ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
+ARDOUR_UI::new_session (std::string predetermined_path)
{
string session_name;
string session_path;
@@ -1818,6 +1810,14 @@ This prevents the session from being loaded."));
new_session = new Session (*engine, path, snap_name, mix_template);
}
+ /* handle this one in a different way than all others, so that its clear what happened */
+
+ catch (AudioEngine::PortRegistrationFailure& err) {
+ error << _("Unable to create all required ports")
+ << endmsg;
+ return -1;
+ }
+
catch (...) {
error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
@@ -2330,7 +2330,7 @@ ARDOUR_UI::cmdline_new_session (string path)
path = str;
}
- new_session (false, path);
+ new_session (path);
_will_create_new_session_automatically = false; /* done it */
return FALSE; /* don't call it again */
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index fb8d87f05d..77418f9ab6 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -128,7 +128,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
_will_create_new_session_automatically = yn;
}
- void new_session(bool startup = false, std::string path = string());
+ void new_session(std::string path = string());
gint cmdline_new_session (string path);
int unload_session ();
void close_session();
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 47d035b54e..2ebcb765c3 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -92,7 +92,7 @@ ARDOUR_UI::install_actions ()
/* the real actions */
- act = ActionManager::register_action (main_actions, X_("New"), _("New"), bind (mem_fun(*this, &ARDOUR_UI::new_session), false, string ()));
+ act = ActionManager::register_action (main_actions, X_("New"), _("New"), bind (mem_fun(*this, &ARDOUR_UI::new_session), string ()));
ActionManager::register_action (main_actions, X_("Open"), _("Open"), mem_fun(*this, &ARDOUR_UI::open_session));
ActionManager::register_action (main_actions, X_("Recent"), _("Recent"), mem_fun(*this, &ARDOUR_UI::open_recent_session));
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index 3e0d6d4e62..1004de19c2 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -79,8 +79,6 @@ shutdown (int status)
} else {
if (ui) {
- msg = _("stopping user interface\n");
- write (1, msg, strlen (msg));
ui->kill();
}
@@ -301,7 +299,7 @@ maybe_load_session ()
if (!session_name.length()) {
ui->hide_splash ();
if (!Config->get_no_new_session_dialog()) {
- ui->new_session (true);
+ ui->new_session ();
}
return true;
@@ -326,7 +324,10 @@ To create it from the command line, start ardour as \"ardour --new %1"), path) <
return false;
}
- ui->load_session (path, name);
+ if (ui->load_session (path, name)) {
+ /* it failed */
+ return false;
+ }
} else {
@@ -338,7 +339,7 @@ To create it from the command line, start ardour as \"ardour --new %1"), path) <
/* Show the NSD */
ui->hide_splash ();
if (!Config->get_no_new_session_dialog()) {
- ui->new_session (true);
+ ui->new_session ();
}
}
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 7c00885228..1da8903a41 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -173,33 +173,39 @@ class AudioDiskstream : public Diskstream
private:
struct ChannelInfo {
-
- Sample *playback_wrap_buffer;
- Sample *capture_wrap_buffer;
- Sample *speed_buffer;
-
- float peak_power;
- boost::shared_ptr<AudioFileSource> fades_source;
- boost::shared_ptr<AudioFileSource> write_source;
-
- Port *source;
- Sample *current_capture_buffer;
- Sample *current_playback_buffer;
+ ChannelInfo ();
+ ~ChannelInfo ();
- RingBufferNPT<Sample> *playback_buf;
- RingBufferNPT<Sample> *capture_buf;
+ void init (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
+ void release ();
- Sample* scrub_buffer;
- Sample* scrub_forward_buffer;
- Sample* scrub_reverse_buffer;
-
- RingBufferNPT<Sample>::rw_vector playback_vector;
- RingBufferNPT<Sample>::rw_vector capture_vector;
-
- RingBufferNPT<CaptureTransition> * capture_transition_buf;
- // the following are used in the butler thread only
- nframes_t curr_capture_cnt;
+ Sample *playback_wrap_buffer;
+ Sample *capture_wrap_buffer;
+ Sample *speed_buffer;
+
+ float peak_power;
+
+ boost::shared_ptr<AudioFileSource> fades_source;
+ boost::shared_ptr<AudioFileSource> write_source;
+
+ Port *source;
+ Sample *current_capture_buffer;
+ Sample *current_playback_buffer;
+
+ RingBufferNPT<Sample> *playback_buf;
+ RingBufferNPT<Sample> *capture_buf;
+
+ Sample* scrub_buffer;
+ Sample* scrub_forward_buffer;
+ Sample* scrub_reverse_buffer;
+
+ RingBufferNPT<Sample>::rw_vector playback_vector;
+ RingBufferNPT<Sample>::rw_vector capture_vector;
+
+ RingBufferNPT<CaptureTransition> * capture_transition_buf;
+ // the following are used in the butler thread only
+ nframes_t curr_capture_cnt;
};
/* The two central butler operations */
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 7274f5646e..83d075a311 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -197,8 +197,7 @@ class AudioEngine : public sigc::trackable
jack_client_t *_jack;
std::string jack_client_name;
Glib::Mutex _process_lock;
- Glib::Mutex session_remove_lock;
- Glib::Cond session_removed;
+ Glib::Cond session_removed;
bool session_remove_pending;
bool _running;
bool _has_run;
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index eb332398da..7c198bb72a 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -199,13 +199,13 @@ class IO : public PBD::StatefulDestructible
static void update_meters();
-private:
+ private:
static sigc::signal<void> Meter;
static Glib::StaticMutex m_meter_signal_lock;
sigc::connection m_meter_connection;
-public:
+ public:
/* automation */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index c71403e125..5aa53e274f 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -933,6 +933,7 @@ class Session : public PBD::StatefulDestructible
private:
int create (bool& new_session, string* mix_template, nframes_t initial_length);
+ void destroy ();
nframes_t compute_initial_length ();
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 66b34956fe..ef3173e87b 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -97,34 +97,6 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
}
void
-AudioDiskstream::init_channel (ChannelInfo &chan)
-{
- chan.playback_wrap_buffer = 0;
- chan.capture_wrap_buffer = 0;
- chan.speed_buffer = 0;
- chan.peak_power = 0.0f;
- chan.source = 0;
- chan.current_capture_buffer = 0;
- chan.current_playback_buffer = 0;
- chan.curr_capture_cnt = 0;
-
- chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
- chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
- chan.capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
-
-
- /* touch the ringbuffer buffers, which will cause
- them to be mapped into locked physical RAM if
- we're running with mlockall(). this doesn't do
- much if we're not.
- */
- memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
- memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
- memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize());
-}
-
-
-void
AudioDiskstream::init (Diskstream::Flag f)
{
Diskstream::init(f);
@@ -141,44 +113,19 @@ AudioDiskstream::init (Diskstream::Flag f)
assert(_n_channels == 1);
}
-void
-AudioDiskstream::destroy_channel (ChannelInfo &chan)
-{
- if (chan.write_source) {
- chan.write_source.reset ();
- }
-
- if (chan.speed_buffer) {
- delete [] chan.speed_buffer;
- }
-
- if (chan.playback_wrap_buffer) {
- delete [] chan.playback_wrap_buffer;
- }
- if (chan.capture_wrap_buffer) {
- delete [] chan.capture_wrap_buffer;
- }
-
- delete chan.playback_buf;
- delete chan.capture_buf;
- delete chan.capture_transition_buf;
-
- chan.playback_buf = 0;
- chan.capture_buf = 0;
-}
-
AudioDiskstream::~AudioDiskstream ()
{
+ notify_callbacks ();
+
{
/* don't be holding this lock as we exit the destructor, glib will wince
visibly since the mutex gets destroyed before we release it.
*/
Glib::Mutex::Lock lm (state_lock);
-
- for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan)
- destroy_channel((*chan));
-
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+ (*chan).release ();
+ }
channels.clear();
}
}
@@ -2107,15 +2054,19 @@ AudioDiskstream::add_channel ()
{
/* XXX need to take lock??? */
- ChannelInfo chan;
+ /* this copies the ChannelInfo, which currently has no buffers. kind
+ of pointless really, but we want the channels list to contain
+ actual objects, not pointers to objects. mostly for convenience,
+ which isn't much in evidence.
+ */
- init_channel (chan);
+ channels.push_back (ChannelInfo());
- chan.speed_buffer = new Sample[speed_buffer_size];
- chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
- chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
+ /* now allocate the buffers */
- channels.push_back (chan);
+ channels.back().init (_session.diskstream_buffer_size(),
+ speed_buffer_size,
+ wrap_buffer_size);
_n_channels = channels.size();
@@ -2127,10 +2078,8 @@ AudioDiskstream::remove_channel ()
{
if (channels.size() > 1) {
/* XXX need to take lock??? */
- ChannelInfo & chan = channels.back();
- destroy_channel (chan);
+ channels.back().release ();
channels.pop_back();
-
_n_channels = channels.size();
return 0;
}
@@ -2310,3 +2259,82 @@ AudioDiskstream::can_become_destructive (bool& requires_bounce) const
requires_bounce = false;
return true;
}
+
+AudioDiskstream::ChannelInfo::ChannelInfo ()
+{
+ playback_wrap_buffer = 0;
+ capture_wrap_buffer = 0;
+ speed_buffer = 0;
+ peak_power = 0.0f;
+ source = 0;
+ current_capture_buffer = 0;
+ current_playback_buffer = 0;
+ curr_capture_cnt = 0;
+ playback_buf = 0;
+ capture_buf = 0;
+ capture_transition_buf = 0;
+}
+
+void
+AudioDiskstream::ChannelInfo::init (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size)
+{
+ speed_buffer = new Sample[speed_size];
+ playback_wrap_buffer = new Sample[wrap_size];
+ capture_wrap_buffer = new Sample[wrap_size];
+
+ playback_buf = new RingBufferNPT<Sample> (bufsize);
+ capture_buf = new RingBufferNPT<Sample> (bufsize);
+ capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
+
+ /* touch the ringbuffer buffers, which will cause
+ them to be mapped into locked physical RAM if
+ we're running with mlockall(). this doesn't do
+ much if we're not.
+ */
+
+ memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize());
+ memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
+ memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize());
+}
+
+AudioDiskstream::ChannelInfo::~ChannelInfo ()
+{
+}
+
+void
+AudioDiskstream::ChannelInfo::release ()
+{
+ if (write_source) {
+ write_source.reset ();
+ }
+
+ if (speed_buffer) {
+ delete [] speed_buffer;
+ speed_buffer = 0;
+ }
+
+ if (playback_wrap_buffer) {
+ delete [] playback_wrap_buffer;
+ playback_wrap_buffer = 0;
+ }
+
+ if (capture_wrap_buffer) {
+ delete [] capture_wrap_buffer;
+ capture_wrap_buffer = 0;
+ }
+
+ if (playback_buf) {
+ delete playback_buf;
+ playback_buf = 0;
+ }
+
+ if (capture_buf) {
+ delete capture_buf;
+ capture_buf = 0;
+ }
+
+ if (capture_transition_buf) {
+ delete capture_transition_buf;
+ capture_transition_buf = 0;
+ }
+}
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 39c5ddcdab..128fc37eb1 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -45,6 +45,12 @@ using namespace PBD;
gint AudioEngine::m_meter_exit;
+static void
+ardour_jack_error (const char* msg)
+{
+ error << "JACK: " << msg << endmsg;
+}
+
AudioEngine::AudioEngine (string client_name)
: ports (new Ports)
{
@@ -76,11 +82,16 @@ AudioEngine::AudioEngine (string client_name)
AudioEngine::~AudioEngine ()
{
- if (_running) {
- jack_client_close (_jack);
+ {
+ Glib::Mutex::Lock tm (_process_lock);
+ session_removed.signal ();
+
+ if (_running) {
+ jack_client_close (_jack);
+ }
+
+ stop_metering_thread ();
}
-
- stop_metering_thread ();
}
void
@@ -407,8 +418,26 @@ AudioEngine::meter_thread ()
void
AudioEngine::set_session (Session *s)
{
+ Glib::Mutex::Lock pl (_process_lock);
+
if (!session) {
+
session = s;
+
+ nframes_t blocksize = jack_get_buffer_size (_jack);
+
+ /* page in as much of the session process code as we
+ can before we really start running.
+ */
+
+ session->process (blocksize);
+ session->process (blocksize);
+ session->process (blocksize);
+ session->process (blocksize);
+ session->process (blocksize);
+ session->process (blocksize);
+ session->process (blocksize);
+ session->process (blocksize);
}
}
@@ -422,12 +451,10 @@ AudioEngine::remove_session ()
if (session) {
session_remove_pending = true;
session_removed.wait(_process_lock);
- }
+ }
} else {
-
session = 0;
-
}
remove_all_ports ();
@@ -461,8 +488,6 @@ AudioEngine::register_input_port (DataType type, const string& portname)
return newport;
} else {
-
- _process_lock.unlock();
throw PortRegistrationFailure();
}
@@ -501,8 +526,6 @@ AudioEngine::register_output_port (DataType type, const string& portname)
return newport;
} else {
-
- _process_lock.unlock();
throw PortRegistrationFailure ();
}
@@ -1015,6 +1038,8 @@ AudioEngine::connect_to_jack (string client_name)
if (status & JackNameNotUnique) {
jack_client_name = jack_get_client_name (_jack);
}
+
+ jack_set_error_function (ardour_jack_error);
return 0;
}
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 77f3a33ff2..1c72697347 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -53,6 +53,7 @@ extern "C" int isnan (double);
extern "C" int isinf (double);
#endif
+#define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (_session.engine().process_lock())
using namespace std;
using namespace ARDOUR;
@@ -624,7 +625,7 @@ IO::disconnect_input (Port* our_port, string other_port, void* src)
}
{
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
{
Glib::Mutex::Lock lm (io_lock);
@@ -660,7 +661,7 @@ IO::connect_input (Port* our_port, string other_port, void* src)
}
{
- Glib::Mutex::Lock em(_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
{
Glib::Mutex::Lock lm (io_lock);
@@ -694,7 +695,7 @@ IO::disconnect_output (Port* our_port, string other_port, void* src)
}
{
- Glib::Mutex::Lock em(_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
{
Glib::Mutex::Lock lm (io_lock);
@@ -727,7 +728,8 @@ IO::connect_output (Port* our_port, string other_port, void* src)
}
{
- Glib::Mutex::Lock em(_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
+
{
Glib::Mutex::Lock lm (io_lock);
@@ -786,7 +788,8 @@ IO::remove_output_port (Port* port, void* src)
IOChange change (NoChange);
{
- Glib::Mutex::Lock em(_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
+
{
Glib::Mutex::Lock lm (io_lock);
@@ -844,7 +847,8 @@ IO::add_output_port (string destination, void* src, DataType type)
type = _default_type;
{
- Glib::Mutex::Lock em(_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
+
{
Glib::Mutex::Lock lm (io_lock);
@@ -896,7 +900,8 @@ IO::remove_input_port (Port* port, void* src)
IOChange change (NoChange);
{
- Glib::Mutex::Lock em(_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
+
{
Glib::Mutex::Lock lm (io_lock);
@@ -956,7 +961,7 @@ IO::add_input_port (string source, void* src, DataType type)
type = _default_type;
{
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
{
Glib::Mutex::Lock lm (io_lock);
@@ -1008,7 +1013,7 @@ int
IO::disconnect_inputs (void* src)
{
{
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
{
Glib::Mutex::Lock lm (io_lock);
@@ -1028,7 +1033,7 @@ int
IO::disconnect_outputs (void* src)
{
{
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
{
Glib::Mutex::Lock lm (io_lock);
@@ -1090,7 +1095,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
setup_peak_meters ();
reset_panner ();
/* pass it on */
- throw err;
+ throw AudioEngine::PortRegistrationFailure();
}
_inputs.push_back (input_port);
@@ -1140,7 +1145,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
}
{
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
Glib::Mutex::Lock lm (io_lock);
Port* port;
@@ -1195,7 +1200,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
setup_peak_meters ();
reset_panner ();
/* pass it on */
- throw err;
+ throw AudioEngine::PortRegistrationFailure();
}
_inputs.push_back (port);
@@ -1228,7 +1233,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
setup_peak_meters ();
reset_panner ();
/* pass it on */
- throw err;
+ throw AudioEngine::PortRegistrationFailure ();
}
_outputs.push_back (port);
@@ -1289,7 +1294,7 @@ IO::ensure_inputs (uint32_t n, bool clear, bool lockit, void* src)
}
if (lockit) {
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
Glib::Mutex::Lock im (io_lock);
changed = ensure_inputs_locked (n, clear, src);
} else {
@@ -1391,7 +1396,7 @@ IO::ensure_outputs (uint32_t n, bool clear, bool lockit, void* src)
/* XXX caller should hold io_lock, but generally doesn't */
if (lockit) {
- Glib::Mutex::Lock em (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
Glib::Mutex::Lock im (io_lock);
changed = ensure_outputs_locked (n, clear, src);
} else {
@@ -2191,7 +2196,7 @@ IO::use_input_connection (Connection& c, void* src)
uint32_t limit;
{
- Glib::Mutex::Lock lm (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
Glib::Mutex::Lock lm2 (io_lock);
limit = c.nports();
@@ -2269,7 +2274,7 @@ IO::use_output_connection (Connection& c, void* src)
uint32_t limit;
{
- Glib::Mutex::Lock lm (_session.engine().process_lock());
+ BLOCK_PROCESS_CALLBACK ();
Glib::Mutex::Lock lm2 (io_lock);
limit = c.nports();
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 45be26c598..c6cd6528d3 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -281,12 +281,13 @@ Session::Session (AudioEngine &eng,
if (new_session) {
if (create (new_session, mix_template, compute_initial_length())) {
cerr << "create failed\n";
+ destroy ();
throw failed_constructor ();
}
}
if (second_stage_init (new_session)) {
- cerr << "2nd state failed\n";
+ destroy ();
throw failed_constructor ();
}
@@ -346,6 +347,7 @@ Session::Session (AudioEngine &eng,
if (new_session) {
if (create (new_session, 0, initial_length)) {
+ destroy ();
throw failed_constructor ();
}
}
@@ -373,6 +375,7 @@ Session::Session (AudioEngine &eng,
Config->set_output_auto_connect (output_ac);
if (second_stage_init (new_session)) {
+ destroy ();
throw failed_constructor ();
}
@@ -389,6 +392,12 @@ Session::Session (AudioEngine &eng,
Session::~Session ()
{
+ destroy ();
+}
+
+void
+Session::destroy ()
+{
/* if we got to here, leaving pending capture state around
is a mistake.
*/
@@ -2930,6 +2939,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
if (cnt > limit) {
error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
+ destroy ();
throw failed_constructor();
}
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 0afa682d58..0c2961c82a 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -99,12 +99,14 @@ void
Session::first_stage_init (string fullpath, string snapshot_name)
{
if (fullpath.length() == 0) {
+ destroy ();
throw failed_constructor();
}
char buf[PATH_MAX+1];
if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
+ destroy ();
throw failed_constructor();
}
@@ -155,7 +157,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_worst_output_latency = 0;
_worst_input_latency = 0;
_worst_track_latency = 0;
- _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
+ _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
_slave = 0;
butler_mixdown_buffer = 0;
butler_gain_buffer = 0;
@@ -307,7 +309,13 @@ Session::second_stage_init (bool new_session)
_engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
_engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
- when_engine_running();
+ try {
+ when_engine_running();
+ }
+
+ catch (...) {
+ return -1;
+ }
send_full_time_code ();
_engine.transport_locate (0);