Skip to content

policy-node: fix potential rescan loop

P V requested to merge pvir/wireplumber:fix-policy-loop-2 into master

policy-node: fix potential rescan loop

SiLink activation might be delayed indefinitely under some error conditions. Currently, policy-node schedules a rescan when it sees a non-activated link on a stream to be moved, which produces busy loop if the si-link doesn't activate.

Instead of rescheduling on non-active si-links, just remove and emit a warning. The si-link then gets removed once it gets activated.


  1. Play audio from Rhythmbox and pause.
  2. Switch default output with pactl between two different outputs
  3. Links from the paused stream stay at "init"

m-si-link: don't wait for establish before activation + cleanup links

SiLink should not wait for WpLinks becoming ESTABLISHED, before activation. That flag shows whether a link has moved away from the "init" state, however, links to e.g. Pulseaudio corked streams can stay in "init" state until uncorking. This causes trouble for policies, which needlessly wait for such links to establish.

The WpLink objects may also be kept alive by other referents, and just unrefing them does not necessarily destroy the PW objects.

Activate SiLink even if the WpLink is still in "init" state. It's enough that the link otherwise successfully establishes.

At dispose time, explicitly request destroying the WpLinks that were created by the SiLink, to ensure they are removed even if there's something else referring to them.

See #152

The problem here seems to be that SiLinks for corked pulse streams never activate, because Wireplumber waits for the link state to transition away from "init", which happens only after uncorking i.e. resuming playback.

This is probably wrong: the si-links should be considered active once the PW Link objects appear regardless of their state. New links to/from suspended/idle nodes will stay in the "init" state, since pw_impl_link_prepare won't start format negotiation for them. policy-node likely should not care about whether the link has started negotiating after creation.

The SiLink should also destroy the links it created when done. Under some conditions it appears the WpLink objects created by SiLink are kept alive by some other referents (probably another activation transition), so they should be explicitly destroyed on SiLink disposal instead of just being unref'd.

This m-si-link change alone should be enough to address the busy loop issue, but it may be the links fail to activate also for other reasons. So in policy-node it's probably better to instead emit a warning and move on, instead of entering a busy loop.

Simple reproducer: corked.c -- run and then change default output.

Edited by P V

Merge request reports