Abstract definition of rt-scheduler policy
[ardour.git] / libs / ardour / automation_watch.cc
index 21d1b6a49d18b92dff060cefd01957b5517d684b..ad05f3ac69b8db0bfac805a30d58dd39f85e6735 100644 (file)
@@ -22,6 +22,7 @@
 #include <glibmm/timer.h>
 
 #include "pbd/compose.h"
+#include "pbd/pthread_utils.h"
 
 #include "ardour/automation_control.h"
 #include "ardour/automation_watch.h"
@@ -60,6 +61,7 @@ AutomationWatch::~AutomationWatch ()
 
        Glib::Threads::Mutex::Lock lm (automation_watch_lock);
        automation_watches.clear ();
+       automation_connections.clear ();
 }
 
 void
@@ -67,7 +69,11 @@ AutomationWatch::add_automation_watch (boost::shared_ptr<AutomationControl> ac)
 {
        Glib::Threads::Mutex::Lock lm (automation_watch_lock);
        DEBUG_TRACE (DEBUG::Automation, string_compose ("now watching control %1 for automation, astate = %2\n", ac->name(), enum_2_string (ac->automation_state())));
-       automation_watches.insert (ac);
+       std::pair<AutomationWatches::iterator, bool> r = automation_watches.insert (ac);
+
+       if (!r.second) {
+               return;
+       }
 
        /* if an automation control is added here while the transport is
         * rolling, make sure that it knows that there is a write pass going
@@ -87,7 +93,7 @@ AutomationWatch::add_automation_watch (boost::shared_ptr<AutomationControl> ac)
         */
 
        boost::weak_ptr<AutomationControl> wac (ac);
-       ac->DropReferences.connect_same_thread (*this, boost::bind (&AutomationWatch::remove_weak_automation_watch, this, wac));
+       ac->DropReferences.connect_same_thread (automation_connections[ac], boost::bind (&AutomationWatch::remove_weak_automation_watch, this, wac));
 }
 
 void
@@ -108,6 +114,7 @@ AutomationWatch::remove_automation_watch (boost::shared_ptr<AutomationControl> a
        Glib::Threads::Mutex::Lock lm (automation_watch_lock);
        DEBUG_TRACE (DEBUG::Automation, string_compose ("remove control %1 from automation watch\n", ac->name()));
        automation_watches.erase (ac);
+       automation_connections.erase (ac);
        ac->list()->set_in_write_pass (false);
 }
 
@@ -128,10 +135,11 @@ AutomationWatch::transport_stop_automation_watches (framepos_t when)
                */
 
                automation_watches.clear ();
+               automation_connections.clear ();
        }
 
        for (AutomationWatches::iterator i = tmp.begin(); i != tmp.end(); ++i) {
-               (*i)->stop_touch (true, when);
+               (*i)->stop_touch (when);
        }
 }
 
@@ -178,6 +186,7 @@ AutomationWatch::timer ()
 void
 AutomationWatch::thread ()
 {
+       pbd_set_thread_priority (pthread_self(), PBD_SCHED_FIFO, -25);
        while (_run_thread) {
                Glib::usleep ((gulong) floor (Config->get_automation_interval_msecs() * 1000));
                timer ();