Fix race where competing-link sweep destroys auto-links before .bound fires
ProcessSavedLinks checked auto_link_proxies by global ID (proxy->id), but this is only set asynchronously in the .bound callback. On a second CoreDone pass (e.g. when virtual Sink ports appear), the sweep could classify a just-created rule link as competing and destroy it. Track (output_port, input_port) on LinkProxy at creation time and match by port pair instead of the racy global ID.
This commit is contained in:
parent
f78970f9e4
commit
ad45683f21
1 changed files with 14 additions and 2 deletions
|
|
@ -125,6 +125,8 @@ struct LinkProxy {
|
|||
bool failed = false;
|
||||
std::string error;
|
||||
uint32_t id = SPA_ID_INVALID;
|
||||
uint32_t output_port = 0;
|
||||
uint32_t input_port = 0;
|
||||
};
|
||||
|
||||
void LinkProxyBound(void* data, uint32_t global_id) {
|
||||
|
|
@ -1026,6 +1028,8 @@ void Client::Impl::CreateAutoLinkAsync(uint32_t output_port, uint32_t input_port
|
|||
auto link_data = std::make_unique<LinkProxy>();
|
||||
link_data->proxy = proxy;
|
||||
link_data->loop = thread_loop;
|
||||
link_data->output_port = output_port;
|
||||
link_data->input_port = input_port;
|
||||
pw_proxy_add_listener(proxy, &link_data->listener, &kLinkProxyEvents, link_data.get());
|
||||
|
||||
std::lock_guard<std::mutex> lock(cache_mutex);
|
||||
|
|
@ -1122,13 +1126,17 @@ void Client::Impl::ProcessSavedLinks() {
|
|||
}
|
||||
}
|
||||
if (!is_ours) {
|
||||
uint32_t out_port = link_entry.second.output_port.value;
|
||||
for (const auto& proxy : auto_link_proxies) {
|
||||
if (proxy && proxy->id == link_id) { is_ours = true; break; }
|
||||
if (proxy && proxy->output_port == out_port &&
|
||||
proxy->input_port == in_port) { is_ours = true; break; }
|
||||
}
|
||||
}
|
||||
if (!is_ours) {
|
||||
uint32_t out_port = link_entry.second.output_port.value;
|
||||
for (const auto& proxy : saved_link_proxies) {
|
||||
if (proxy && proxy->id == link_id) { is_ours = true; break; }
|
||||
if (proxy && proxy->output_port == out_port &&
|
||||
proxy->input_port == in_port) { is_ours = true; break; }
|
||||
}
|
||||
}
|
||||
if (!is_ours) {
|
||||
|
|
@ -1167,6 +1175,8 @@ void Client::Impl::CreateSavedLinkAsync(uint32_t output_port,
|
|||
auto link_data = std::make_unique<LinkProxy>();
|
||||
link_data->proxy = proxy;
|
||||
link_data->loop = thread_loop;
|
||||
link_data->output_port = output_port;
|
||||
link_data->input_port = input_port;
|
||||
pw_proxy_add_listener(proxy, &link_data->listener, &kLinkProxyEvents,
|
||||
link_data.get());
|
||||
|
||||
|
|
@ -1874,6 +1884,8 @@ Result<Link> Client::CreateLink(PortId output, PortId input, const LinkOptions&
|
|||
auto link_proxy = std::make_unique<LinkProxy>();
|
||||
link_proxy->proxy = proxy;
|
||||
link_proxy->loop = impl_->thread_loop;
|
||||
link_proxy->output_port = output.value;
|
||||
link_proxy->input_port = input.value;
|
||||
pw_proxy_add_listener(proxy, &link_proxy->listener, &kLinkProxyEvents, link_proxy.get());
|
||||
|
||||
int wait_attempts = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue