-/// Takes data in, processes it and passes it on to another sink
-template <typename TIn, typename TOut>
-class GraphSinkVertex : public GraphSink<TIn> {
- public:
- GraphSinkVertex () {}
- virtual ~GraphSinkVertex () {}
-
- void pipe_to (boost::shared_ptr<GraphSink<TOut> > dest) {
- piped_to = dest;
- }
-
- nframes_t write (TIn * data, nframes_t frames)
- {
- if (!piped_to) {
- return -1;
- }
- return process (data, frames);
- }
-
- virtual void set_end_of_input (bool state = true)
- {
- if (!piped_to) {
- return;
- }
- piped_to->set_end_of_input (state);
- GraphSink<TIn>::end_of_input = state;
- }
-
- protected:
- boost::shared_ptr<GraphSink<TOut> > piped_to;
-
- /* process must process data,
- use piped_to->write to write the data
- and return number of frames written */
- virtual nframes_t process (TIn * data, nframes_t frames) = 0;
+ bool in_process_thread () const;
+
+protected:
+ virtual void session_going_away ();
+
+private:
+ volatile bool _threads_active;
+
+ void reset_thread_list ();
+ void drop_threads ();
+
+ node_list_t _nodes_rt[2];
+
+ node_list_t _init_trigger_list[2];
+
+ std::vector<GraphNode *> _trigger_queue;
+ pthread_mutex_t _trigger_mutex;
+
+ PBD::Semaphore _execution_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;
+
+ // chain swapping
+ Glib::Threads::Mutex _swap_mutex;
+ Glib::Threads::Cond _cleanup_cond;
+ volatile int _current_chain;
+ volatile int _pending_chain;
+ volatile int _setup_chain;
+
+ // parameter caches.
+ 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 ();