From b3b10db5290f9c17878e5d5ca376a60626901411 Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Thu, 20 May 2021 11:13:50 -0400 Subject: [PATCH] policy: don't link endpoints on startup Sometimes the default device node might not exist when reevaluating endpoints for the first time on startup, so the policy would link endpoints to another device node. Then, the default device node appears and the policy moves the endpoints to the default device node while the previous link has not finish its activation yet. This race condition can cause endpoint links to fail when being activated. Delaying the reevaluation of endpoint links until the first client link is created avoids this issue. --- src/scripts/policy-endpoint-device.lua | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/scripts/policy-endpoint-device.lua b/src/scripts/policy-endpoint-device.lua index 2894abe0..5e30863d 100644 --- a/src/scripts/policy-endpoint-device.lua +++ b/src/scripts/policy-endpoint-device.lua @@ -176,15 +176,21 @@ end default_nodes = Plugin.find("default-nodes-api") siendpoints_om = ObjectManager { Interest { type = "SiEndpoint" }} silinkables_om = ObjectManager { Interest { type = "SiLinkable", - -- only handle si-audio-adapter and si-node - Constraint { - "si.factory.name", "c", "si-audio-adapter", "si-node", type = "pw-global" }, + -- only handle device si-audio-adapter items + Constraint { "si.factory.name", "=", "si-audio-adapter", type = "pw-global" }, + Constraint { "is.device", "=", true, type = "pw-global" }, } } silinks_om = ObjectManager { Interest { type = "SiLink", -- only handle links created by this policy Constraint { "is.policy.endpoint.device.link", "=", true, type = "pw-global" }, } } +clientlinks_om = ObjectManager { + Interest { + type = "SiLink", + Constraint { "is.policy.endpoint.client.link", "=", true }, + }, +} -- listen for default node changes if config.follow is enabled if config.follow then @@ -193,10 +199,20 @@ if config.follow then end) end -silinkables_om:connect("objects-changed", function (om) +-- start reevaluating endpoints when the first client link is created +clientlinks_om:connect("object-added", function (om, l) reevaluateLinks () + + -- stop listening to client links from now on + clientlinks_om = nil + + -- only reevaluate endpoints when device nodes change from now on + silinkables_om:connect("objects-changed", function (om) + reevaluateLinks () + end) end) siendpoints_om:activate() silinkables_om:activate() silinks_om:activate() +clientlinks_om:activate()