rename ProcessSemaphore to Semaphore (libs)
[ardour.git] / libs / ardour / ardour / graph.h
index e8bae4a32ce45018ed9b325d0c6b6d5d55f8988c..239f9ad1abec406c2976e2d1dc48d83cdad47221 100644 (file)
@@ -1,5 +1,6 @@
 /*
     Copyright (C) 2010 Paul Davis
+    Author: Torben Hohn
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 
 #ifndef __ardour_graph_h__
 #define __ardour_graph_h__
 
-
 #include <list>
 #include <set>
 #include <vector>
 
 #include <boost/shared_ptr.hpp>
 
-#include <glib/gatomic.h>
-#include <cassert>
+#include <glib.h>
 
-#include <pthread.h>
-#include <semaphore.h>
+#include "pbd/semutils.h"
 
-#include <ardour/types.h>
-#include <ardour/session_handle.h>
+#include "ardour/libardour_visibility.h"
+#include "ardour/types.h"
+#include "ardour/audio_backend.h"
+#include "ardour/session_handle.h"
 
 namespace ARDOUR
 {
@@ -46,25 +45,23 @@ class Graph;
 
 class Route;
 class Session;
+class GraphEdges;
 
 typedef boost::shared_ptr<GraphNode> node_ptr_t;
-typedef boost::shared_ptr<Graph> graph_ptr_t;
 
 typedef std::list< node_ptr_t > node_list_t;
 typedef std::set< node_ptr_t > node_set_t;
 
-
-
-class Graph : public SessionHandleRef
+class LIBARDOUR_API Graph : public SessionHandleRef
 {
-    public:
-       Graph( Session & session );
+public:
+       Graph (Session & session);
 
        void prep();
-       void trigger( GraphNode * n );
-       void rechain( boost::shared_ptr<RouteList> r );
+       void trigger (GraphNode * n);
+       void rechain (boost::shared_ptr<RouteList>, GraphEdges const &);
 
-       void dump( int chain );
+       void dump (int chain);
        void process();
        void dec_ref();
        void restart_cycle();
@@ -73,65 +70,78 @@ class Graph : public SessionHandleRef
        void helper_thread();
        void main_thread();
 
-       int silent_process_routes (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
-                bool can_record, bool rec_monitors_input, bool& need_butler );
+       int silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
+                                  bool& need_butler);
+
+       int process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
+                           bool& need_butler);
 
-       int process_routes (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
-                bool can_record, bool rec_monitors_input, bool& need_butler );
+       int routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
+                           bool non_rt_pending, int declick);
 
-        int routes_no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, 
-                bool non_rt_pending, bool can_record, int declick);
+       void process_one_route (Route * route);
 
-       void process_one_route( Route * route );
+       void clear_other_chain ();
 
-    protected:
-        virtual void session_going_away ();
+       bool in_process_thread () const;
+
+protected:
+       virtual void session_going_away ();
+
+private:
+       volatile bool        _threads_active;
+
+       void reset_thread_list ();
+       void drop_threads ();
 
-    private:
-        std::list<Glib::Thread *> _thread_list;
-        volatile bool _quit_threads;
-        
-       node_list_t _nodes;
        node_list_t _nodes_rt[2];
 
        node_list_t _init_trigger_list[2];
 
        std::vector<GraphNode *> _trigger_queue;
-       pthread_mutex_t _trigger_mutex;
-
+       pthread_mutex_t          _trigger_mutex;
 
-       sem_t _execution_sem;
+       PBD::Semaphore _execution_sem;
 
-       sem_t _callback_start_sem;
-       sem_t _callback_done_sem;
+       /** Signalled to start a run of the graph for a process callback */
+       PBD::Semaphore _callback_start_sem;
+       PBD::Semaphore _callback_done_sem;
+       PBD::Semaphore _cleanup_sem;
 
+       /** The number of processing threads that are asleep */
        volatile gint _execution_tokens;
+       /** The number of unprocessed nodes that do not feed any other node; updated during processing */
        volatile gint _finished_refcount;
+       /** The initial number of nodes that do not feed any other node (for each chain) */
        volatile gint _init_finished_refcount[2];
 
-        bool _graph_empty;
+       bool _graph_empty;
 
        // chain swapping
-       pthread_mutex_t _swap_mutex;
+       Glib::Threads::Mutex  _swap_mutex;
+        Glib::Threads::Cond   _cleanup_cond;
        volatile int _current_chain;
        volatile int _pending_chain;
        volatile int _setup_chain;
 
        // parameter caches.
-       nframes_t       _process_nframes;
-       sframes_t       _process_start_frame;
-       sframes_t       _process_end_frame;
-       bool            _process_can_record;
-       bool            _process_rec_monitors_input;
-       bool            _process_non_rt_pending;
-       int             _process_declick;
-
-       bool            _process_silent;
-       bool            _process_noroll;
-       int             _process_retval;
-       bool            _process_need_butler;
+       pframes_t  _process_nframes;
+       framepos_t _process_start_frame;
+       framepos_t _process_end_frame;
+       bool       _process_can_record;
+       bool       _process_non_rt_pending;
+       int        _process_declick;
+
+       bool _process_silent;
+       bool _process_noroll;
+       int  _process_retval;
+       bool _process_need_butler;
+
+       // enginer / thread connection
+       PBD::ScopedConnectionList engine_connections;
+       void engine_stopped ();
 };
 
-}
+} // namespace
 
-#endif
+#endif /* __ardour_graph_h__ */