resolve gtk + VST threading issues
[ardour.git] / libs / ardour / route.cc
index e86d2c5b0dead97a75d3e3b72ab263c7b6c1e806..bcbf14bdafceaa1fd2b6fcd3498b65542b2c79f4 100644 (file)
@@ -419,6 +419,9 @@ Route::process_output_buffers (BufferSet& bufs,
                               framepos_t start_frame, framepos_t end_frame, pframes_t nframes,
                               int declick, bool gain_automation_ok)
 {
+       /* Caller must hold process lock */
+       assert (!AudioEngine::instance()->process_lock().trylock());
+
        Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
        assert(lm.locked());
 
@@ -544,6 +547,7 @@ Route::monitor_run (framepos_t start_frame, framepos_t end_frame, pframes_t nfra
 {
        assert (is_monitor());
        BufferSet& bufs (_session.get_route_buffers (n_process_buffers()));
+       fill_buffers_with_input (bufs, _input, nframes);
        passthru (bufs, start_frame, end_frame, nframes, declick);
 }
 
@@ -1069,7 +1073,8 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
 
                } else if (node.name() == "Send") {
 
-                       processor.reset (new Send (_session, _pannable, _mute_master));
+                       boost::shared_ptr<Pannable> sendpan (new Pannable (_session));
+                       processor.reset (new Send (_session, sendpan, _mute_master));
 
                } else {
 
@@ -1381,7 +1386,16 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
 {
        // TODO once the export point can be configured properly, do something smarter here
        if (processor == _capturing_processor) {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
+               if (need_process_lock) {
+                       lx.acquire();
+               }
+
                _capturing_processor.reset();
+
+               if (need_process_lock) {
+                       lx.release();
+               }
        }
 
        /* these can never be removed */
@@ -1401,7 +1415,12 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
                if (need_process_lock) {
                        lx.acquire();
                }
-               Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+
+               /* Caller must hold process lock */
+               assert (!AudioEngine::instance()->process_lock().trylock());
+
+               Glib::Threads::RWLock::WriterLock lm (_processor_lock); // XXX deadlock after export
+
                ProcessorState pstate (this);
 
                ProcessorList::iterator i;
@@ -1567,58 +1586,6 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
        return 0;
 }
 
-void
-Route::set_custom_panner_uri (std::string const panner_uri)
-{
-       if (_in_configure_processors) {
-               DEBUG_TRACE (DEBUG::Panning, string_compose (_("Route::set_custom_panner_uri '%1' -- called while in_configure_processors\n"), name()));
-               return;
-       }
-
-       if (!_main_outs->panner_shell()->set_user_selected_panner_uri(panner_uri)) {
-               DEBUG_TRACE (DEBUG::Panning, string_compose (_("Route::set_custom_panner_uri '%1 '%2' -- no change needed\n"), name(), panner_uri));
-               /* no change needed */
-               return;
-       }
-
-       DEBUG_TRACE (DEBUG::Panning, string_compose (_("Route::set_custom_panner_uri '%1 '%2' -- reconfigure I/O\n"), name(), panner_uri));
-
-       /* reconfigure I/O -- re-initialize panner modules */
-       {
-               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
-               Glib::Threads::RWLock::WriterLock lm (_processor_lock);
-
-               for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
-                       boost::shared_ptr<Delivery> dl;
-                       boost::shared_ptr<Panner> panner;
-                       if ((dl = boost::dynamic_pointer_cast<Delivery> (*p)) == 0) {
-                               continue;
-                       }
-                       if (!dl->panner_shell()) {
-                               continue;
-                       }
-                       if (!(panner = dl->panner_shell()->panner())) {
-                               continue;
-                       }
-                       /* _main_outs has already been set before the loop.
-                        * Ignore the return status here. It need reconfiguration */
-                       if (dl->panner_shell() != _main_outs->panner_shell()) {
-                               if (!dl->panner_shell()->set_user_selected_panner_uri(panner_uri)) {
-                                       continue;
-                               }
-                       }
-
-                       ChanCount in = panner->in();
-                       ChanCount out = panner->out();
-                       dl->panner_shell()->configure_io(in, out);
-                       dl->panner_shell()->pannable()->set_panner(dl->panner_shell()->panner());
-               }
-       }
-
-       processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
-       _session.set_dirty ();
-}
-
 void
 Route::reset_instrument_info ()
 {
@@ -2552,7 +2519,7 @@ Route::set_processor_state (const XMLNode& node)
 
                                if (prop->value() == "intsend") {
 
-                                       processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0)));
+                                       processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Aux, true));
 
                                } else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
                                           prop->value() == "lv2" ||
@@ -2568,7 +2535,7 @@ Route::set_processor_state (const XMLNode& node)
 
                                } else if (prop->value() == "send") {
 
-                                       processor.reset (new Send (_session, _pannable, _mute_master));
+                                       processor.reset (new Send (_session, _pannable, _mute_master, Delivery::Send, true));
 
                                } else {
                                        error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
@@ -2758,7 +2725,8 @@ Route::add_aux_send (boost::shared_ptr<Route> route, boost::shared_ptr<Processor
 
                {
                        Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-                       listener.reset (new InternalSend (_session, _pannable, _mute_master, route, Delivery::Aux));
+                       boost::shared_ptr<Pannable> sendpan (new Pannable (_session));
+                       listener.reset (new InternalSend (_session, sendpan, _mute_master, route, Delivery::Aux));
                }
 
                add_processor (listener, before);
@@ -3118,6 +3086,7 @@ Route::set_meter_point (MeterPoint p, bool force)
        bool meter_was_visible_to_user = _meter->display_to_user ();
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
 
                maybe_note_meter_position ();
@@ -3203,12 +3172,16 @@ Route::listen_position_changed ()
 boost::shared_ptr<CapturingProcessor>
 Route::add_export_point()
 {
+       Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
        if (!_capturing_processor) {
+               lm.release();
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+               Glib::Threads::RWLock::WriterLock lw (_processor_lock);
 
                _capturing_processor.reset (new CapturingProcessor (_session));
                _capturing_processor->activate ();
 
-               configure_processors (0);
+               configure_processors_unlocked (0);
 
        }
 
@@ -4188,7 +4161,7 @@ Route::non_realtime_locate (framepos_t pos)
 
        {
                //Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
-               Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+               Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
                
                for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
                        (*i)->transport_located (pos);