mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
impl-link: improve feedback loop check
Mark peer nodes as visited and only visit them once. Reduces the complexity a lot. Limit the number of hops we check to 32 to avoid excessive work.
This commit is contained in:
parent
298dfa7da4
commit
6600d93d5d
1 changed files with 18 additions and 12 deletions
|
|
@ -41,6 +41,8 @@
|
|||
|
||||
#define NAME "link"
|
||||
|
||||
#define MAX_HOPS 32
|
||||
|
||||
#define pw_link_resource_info(r,...) pw_resource_call(r,struct pw_link_events,info,0,__VA_ARGS__)
|
||||
|
||||
/** \cond */
|
||||
|
|
@ -928,26 +930,30 @@ static const struct pw_impl_node_events output_node_events = {
|
|||
.active_changed = node_active_changed,
|
||||
};
|
||||
|
||||
static bool pw_impl_node_can_reach(struct pw_impl_node *output, struct pw_impl_node *input)
|
||||
static bool pw_impl_node_can_reach(struct pw_impl_node *output, struct pw_impl_node *input, int hop)
|
||||
{
|
||||
struct pw_impl_port *p;
|
||||
struct pw_impl_link *l;
|
||||
|
||||
output->visited = true;
|
||||
|
||||
if (output == input)
|
||||
return true;
|
||||
|
||||
spa_list_for_each(p, &output->output_ports, link) {
|
||||
struct pw_impl_link *l;
|
||||
if (hop == MAX_HOPS) {
|
||||
pw_log_warn("exceeded hops (%d) %s -> %s", hop, output->name, input->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
spa_list_for_each(p, &output->output_ports, link) {
|
||||
spa_list_for_each(l, &p->links, output_link)
|
||||
l->input->node->visited = l->feedback;
|
||||
}
|
||||
spa_list_for_each(p, &output->output_ports, link) {
|
||||
spa_list_for_each(l, &p->links, output_link) {
|
||||
if (l->feedback)
|
||||
if (l->input->node->visited)
|
||||
continue;
|
||||
if (l->input->node == input)
|
||||
return true;
|
||||
}
|
||||
spa_list_for_each(l, &p->links, output_link) {
|
||||
if (l->feedback)
|
||||
continue;
|
||||
if (pw_impl_node_can_reach(l->input->node, input))
|
||||
if (pw_impl_node_can_reach(l->input->node, input, hop+1))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1091,7 +1097,7 @@ struct pw_impl_link *pw_context_create_link(struct pw_context *context,
|
|||
goto error_no_mem;
|
||||
|
||||
this = &impl->this;
|
||||
this->feedback = pw_impl_node_can_reach(input_node, output_node);
|
||||
this->feedback = pw_impl_node_can_reach(input_node, output_node, 0);
|
||||
pw_properties_set(properties, PW_KEY_LINK_FEEDBACK, this->feedback ? "true" : NULL);
|
||||
|
||||
pw_log_debug(NAME" %p: new out-port:%p -> in-port:%p", this, output, input);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue