Atomically setup/update bundle list

Previously bundles were added one at a time, each taking a
RCUWriter. This lead to issues when another thread concurrently
reads the list.

This fixes an issue with LiveTrax, auto-connecting the monitor bus.
This commit is contained in:
Robin Gareus 2026-01-23 23:02:33 +01:00
parent 872f6869a7
commit 6e64838296
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 21 additions and 17 deletions

View file

@ -2359,6 +2359,7 @@ private:
void setup_click ();
void setup_click_state (const XMLNode*);
void setup_bundles ();
void setup_bundles_rcu ();
void port_registry_changed ();
void probe_ctrl_surfaces ();

View file

@ -94,19 +94,17 @@ Session::bundle_by_name (string name) const
}
void
Session::setup_bundles ()
Session::setup_bundles_rcu ()
{
RCUWriter<BundleList> writer (_bundles);
std::shared_ptr<BundleList> b = writer.get_copy ();
{
RCUWriter<BundleList> writer (_bundles);
std::shared_ptr<BundleList> b = writer.get_copy ();
for (BundleList::iterator i = b->begin(); i != b->end();) {
if (std::dynamic_pointer_cast<UserBundle>(*i)) {
++i;
continue;
}
i = b->erase(i);
for (BundleList::iterator i = b->begin(); i != b->end();) {
if (std::dynamic_pointer_cast<UserBundle>(*i)) {
++i;
continue;
}
i = b->erase(i);
}
std::vector<string> inputs[DataType::num_types];
@ -158,7 +156,7 @@ Session::setup_bundles ()
c->add_channel (_("mono"), DataType::AUDIO);
c->set_port (0, outputs[DataType::AUDIO][np]);
add_bundle (c, false);
b->push_back (c);
}
/* stereo output bundles */
@ -180,7 +178,7 @@ Session::setup_bundles ()
c->add_channel (_("R"), DataType::AUDIO);
c->set_port (1, outputs[DataType::AUDIO][np + 1]);
add_bundle (c, false);
b->push_back (c);
}
}
@ -200,7 +198,7 @@ Session::setup_bundles ()
c->add_channel (_("mono"), DataType::AUDIO);
c->set_port (0, inputs[DataType::AUDIO][np]);
add_bundle (c, false);
b->push_back (c);
}
/* stereo input bundles */
@ -223,7 +221,7 @@ Session::setup_bundles ()
c->add_channel (_("R"), DataType::AUDIO);
c->set_port (1, inputs[DataType::AUDIO][np + 1]);
add_bundle (c, false);
b->push_back (c);
}
}
@ -241,7 +239,7 @@ Session::setup_bundles ()
std::shared_ptr<Bundle> c (new Bundle (n, false));
c->add_channel ("", DataType::MIDI);
c->set_port (0, inputs[DataType::MIDI][np]);
add_bundle (c, false);
b->push_back (c);
}
/* MIDI output bundles */
@ -257,9 +255,14 @@ Session::setup_bundles ()
std::shared_ptr<Bundle> c (new Bundle (n, true));
c->add_channel ("", DataType::MIDI);
c->set_port (0, outputs[DataType::MIDI][np]);
add_bundle (c, false);
b->push_back (c);
}
/* RCUWriter leaves scope, commit changes */
}
// we trust the backend to only calls us if there's a change
void
Session::setup_bundles ()
{
setup_bundles_rcu ();
BundleAddedOrRemoved (); /* EMIT SIGNAL */
}