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
This commit is contained in:
parent
b5f497c0c9
commit
ca81401b14
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
ChannelInfo ();
|
||||
~ChannelInfo ();
|
||||
|
||||
Port *source;
|
||||
Sample *current_capture_buffer;
|
||||
Sample *current_playback_buffer;
|
||||
void init (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
|
||||
void release ();
|
||||
|
||||
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;
|
||||
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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -96,34 +96,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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
@ -388,6 +391,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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user