13
0

take process lock when adding processors:

fixes possible crash if a processor modifies port-count

1. a processor is inserted and activated with processor-lock held
2. only after that the process_lock() is taken, configure_processors() is called which reconfigures-IO

BUT if the processor that is inserted changes the channel count AND audio is processed before IOs are reconfigured
 -> possible crash (invalid port-buffers)

To reproduce: Bus1 (2in, 3out), Bus2 (2in, 3out)
- add a send from Bus1 to Bus2,
- then add a processor to Bus1, just before the send which
  increases the channel-count to 4 -> occasional crash or assert.
This commit is contained in:
Robin Gareus 2014-01-12 21:47:15 +01:00 committed by Paul Davis
parent ac8e258e15
commit ac8eb0581d

View File

@ -947,6 +947,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
{ {
Glib::Threads::RWLock::WriterLock lm (_processor_lock); Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this); ProcessorState pstate (this);
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
boost::shared_ptr<PluginInsert> pi; boost::shared_ptr<PluginInsert> pi;
boost::shared_ptr<PortInsert> porti; boost::shared_ptr<PortInsert> porti;
@ -986,8 +987,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
// configure redirect ports properly, etc. // configure redirect ports properly, etc.
{ {
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) { if (configure_processors_unlocked (err)) {
pstate.restore (); pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ... configure_processors_unlocked (0); // it worked before we tried to add it ...
@ -1117,6 +1116,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
{ {
Glib::Threads::RWLock::WriterLock lm (_processor_lock); Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this); ProcessorState pstate (this);
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) { for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
@ -1137,8 +1137,8 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
(*i)->activate (); (*i)->activate ();
} }
/* Think: does this really need to be called for every processor in the loop? */
{ {
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) { if (configure_processors_unlocked (err)) {
pstate.restore (); pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ... configure_processors_unlocked (0); // it worked before we tried to add it ...