move latency-recompute into dedicated thread.
authorRobin Gareus <robin@gareus.org>
Sat, 9 Jul 2016 15:42:58 +0000 (17:42 +0200)
committerRobin Gareus <robin@gareus.org>
Sat, 9 Jul 2016 15:42:58 +0000 (17:42 +0200)
this fixes an issue with jack1 and jack_latency_recompute() since must not
send a server request from inside the server callback.

libs/ardour/ardour/route.h
libs/ardour/ardour/session.h
libs/ardour/plugin_insert.cc
libs/ardour/session.cc

index 9d16c00ba3e438d556e559a6db37b4063a8cc039..bef1a54569ab18755e269ef8b275b8acc656288e 100644 (file)
@@ -360,6 +360,7 @@ public:
        /** the processors have changed; the parameter indicates what changed */
        PBD::Signal1<void,RouteProcessorChange> processors_changed;
        PBD::Signal1<void,void*> record_enable_changed;
+       PBD::Signal0<void> processor_latency_changed;
        /** the metering point has changed */
        PBD::Signal0<void>       meter_change;
        PBD::Signal0<void>       signal_latency_changed;
index ebafdd82f67d97ca815b198edfc4288e12ec56d5..82c9231cfb95fa2f10cee157b67525541e0ae50c 100644 (file)
@@ -1509,8 +1509,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        typedef std::queue<AutoConnectRequest> AutoConnectQueue;
        Glib::Threads::Mutex  _auto_connect_queue_lock;
        AutoConnectQueue _auto_connect_queue;
+       guint _latency_recompute_pending;
 
        void auto_connect (const AutoConnectRequest&);
+       void queue_latency_recompute ();
 
        /* SessionEventManager interface */
 
index 4bbeed5cf1dbd80216967665c082a27aa2a4d2f4..0beb4c2fdb703b2b01e82fbe5562b8dcaf638dfd 100644 (file)
@@ -2959,10 +2959,8 @@ PluginInsert::latency_changed ()
 {
        // this is called in RT context, LatencyChanged is emitted after run()
        _latency_changed = true;
-#if 1 // TODO check possible deadlock in RT-context (esp. with jack) latency-callback.
        // XXX This also needs a proper API not an owner() hack.
-       static_cast<Route*>(owner ())->processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
-#endif
+       static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
 }
 
 void
index bf8291e4b0a24b9c256cd77ed0cc5c0d2cdd96d0..74f20306d2e54a9e6133d69c1b1a828a46b69a1d 100644 (file)
@@ -279,6 +279,7 @@ Session::Session (AudioEngine &eng,
        , _reconnecting_routes_in_progress (false)
        , _route_deletion_in_progress (false)
        , destructive_index (0)
+       , _latency_recompute_pending (0)
        , _track_number_decimals(1)
        , default_fade_steepness (0)
        , default_fade_msecs (0)
@@ -3418,6 +3419,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
 
                r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
                r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
+               r->processor_latency_changed.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
 
                if (r->is_master()) {
                        _master_out = r;
@@ -6838,6 +6840,16 @@ Session::auto_connect_route (boost::shared_ptr<Route> route, bool connect_inputs
        }
 }
 
+void
+Session::queue_latency_recompute ()
+{
+       g_atomic_int_inc (&_latency_recompute_pending);
+       if (pthread_mutex_trylock (&_auto_connect_mutex) == 0) {
+               pthread_cond_signal (&_auto_connect_cond);
+               pthread_mutex_unlock (&_auto_connect_mutex);
+       }
+}
+
 void
 Session::auto_connect (const AutoConnectRequest& ar)
 {
@@ -7003,6 +7015,10 @@ Session::auto_connect_thread_run ()
                        }
                }
 
+               while (g_atomic_int_and (&_latency_recompute_pending, 0)) {
+                       update_latency_compensation ();
+               }
+
                pthread_cond_wait (&_auto_connect_cond, &_auto_connect_mutex);
        }
        pthread_mutex_unlock (&_auto_connect_mutex);