add Session::StateProtector
authorRobin Gareus <robin@gareus.org>
Sat, 28 Jun 2014 19:27:36 +0000 (21:27 +0200)
committerRobin Gareus <robin@gareus.org>
Sat, 28 Jun 2014 20:02:20 +0000 (22:02 +0200)
temp. disable save during batch updates, save once at
the end.

libs/ardour/ardour/session.h
libs/ardour/session.cc
libs/ardour/session_state.cc

index f5266154f4e528d8bad37f2731b79491605deda9..788d4d9fcb25f8d7b70f4127c67ed9dd7634b51f 100644 (file)
@@ -429,6 +429,23 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        StateOfTheState state_of_the_state() const { return _state_of_the_state; }
 
+       class StateProtector {
+               public:
+                       StateProtector (Session* s) : _session (s) {
+                               g_atomic_int_inc (&s->_suspend_save);
+                       }
+                       ~StateProtector () {
+                               if (g_atomic_int_dec_and_test (&_session->_suspend_save)) {
+                                       while (_session->_save_queued) {
+                                               _session->_save_queued = false;
+                                               _session->save_state ("");
+                                       }
+                               }
+                       }
+               private:
+                       Session * _session;
+       };
+
        void add_route_group (RouteGroup *);
        void remove_route_group (RouteGroup&);
        void reorder_route_groups (std::list<RouteGroup*>);
@@ -1099,6 +1116,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        bool             state_was_pending;
        StateOfTheState _state_of_the_state;
 
+       friend class    StateProtector;
+       gint            _suspend_save; /* atomic */
+       volatile bool   _save_queued;
+
        void     auto_save();
        int      load_options (const XMLNode&);
        int      load_state (std::string snapshot_name);
@@ -1648,6 +1669,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath);
 };
 
+
 } // namespace ARDOUR
 
 #endif /* __ardour_session_h__ */
index 4a3ce009ebfa9449ad5eb7804689160e4f3c9a8f..b4ae76c1caaa84e3c16e06476098d6682cd1563c 100644 (file)
@@ -194,6 +194,8 @@ Session::Session (AudioEngine &eng,
        , state_tree (0)
        , state_was_pending (false)
        , _state_of_the_state (StateOfTheState(CannotSave|InitialConnecting|Loading))
+       , _suspend_save (0)
+       , _save_queued (false)
        , _last_roll_location (0)
        , _last_roll_or_reversal_location (0)
        , _last_record_location (0)
index c9267b058f62a2933c4cd3309f0b4cf30ce22eca..6979f88dcb3389a48d4ffa896b5ba9fd8caa0300 100644 (file)
@@ -669,6 +669,12 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                return 1;
        }
 
+       if (g_atomic_int_get(&_suspend_save)) {
+               _save_queued = true;
+               return 1;
+       }
+       _save_queued = false;
+
        if (!_engine.connected ()) {
                error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
                                          PROGRAM_NAME)