Allow to change process graph while auditioning

This fixes an issue with adding/removing tracks while auditioning.

Session::remove_routes() calls Graph::clear_other_chain(),
which will block until the graph chains have been swapped.
This commit is contained in:
Robin Gareus
2021-09-15 04:02:27 +02:00
parent 5816ca31b8
commit 5eee8bf1a3
3 changed files with 35 additions and 2 deletions

View File

@@ -74,6 +74,7 @@ public:
void process_one_route (Route* route);
void clear_other_chain ();
void swap_process_chain ();
bool in_process_thread () const;
@@ -85,7 +86,7 @@ private:
void drop_threads ();
void run_one ();
void main_thread ();
void prep ();
void prep (bool check_pending_chain = true);
void dump (int chain) const;
node_list_t _nodes_rt[2];

View File

@@ -227,9 +227,37 @@ Graph::clear_other_chain ()
}
void
Graph::prep ()
Graph::swap_process_chain ()
{
/* Intended to be called Session::process_audition.
* Must not be called while the graph is processing.
*/
bool need_prep = false;
if (_swap_mutex.trylock ()) {
/* swap mutex acquired */
if (_current_chain != _pending_chain) {
/* use new chain */
_setup_chain = _current_chain;
_current_chain = _pending_chain;
_trigger_queue.clear ();
/* ensure that all nodes can be queued */
_trigger_queue.reserve (_nodes_rt[_current_chain].size ());
g_atomic_int_set (&_trigger_queue_size, 0);
_cleanup_cond.signal ();
need_prep = true;
}
_swap_mutex.unlock ();
}
if (need_prep) {
prep (false);
}
}
void
Graph::prep (bool check_pending_chain)
{
if (check_pending_chain && _swap_mutex.trylock ()) {
/* swap mutex acquired */
if (_current_chain != _pending_chain) {
/* use new chain */

View File

@@ -730,6 +730,10 @@ Session::process_audition (pframes_t nframes)
}
}
if (_process_graph) {
_process_graph->swap_process_chain ();
}
/* run the auditioner, and if it says we need butler service, ask for it */
if (auditioner->play_audition (nframes) > 0) {