link-target.lua: change into a async hook
link setup is a asynchronous action, async hook serves the purpose well here. The code dependent on links will be less error prone with this design.
This commit is contained in:

committed by
Julian Bouzas

parent
a8aeb1010e
commit
4b153ec553
@@ -10,7 +10,7 @@
|
|||||||
local putils = require ("policy-utils")
|
local putils = require ("policy-utils")
|
||||||
local cutils = require ("common-utils")
|
local cutils = require ("common-utils")
|
||||||
|
|
||||||
SimpleEventHook {
|
AsyncEventHook {
|
||||||
name = "linking/link-target",
|
name = "linking/link-target",
|
||||||
after = "linking/prepare-link",
|
after = "linking/prepare-link",
|
||||||
interests = {
|
interests = {
|
||||||
@@ -18,124 +18,146 @@ SimpleEventHook {
|
|||||||
Constraint { "event.type", "=", "select-target" },
|
Constraint { "event.type", "=", "select-target" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
execute = function (event)
|
steps = {
|
||||||
local source, om, si, si_props, si_flags, target =
|
start = {
|
||||||
putils:unwrap_find_target_event (event)
|
next = "link_activated",
|
||||||
|
execute = function (event, transition)
|
||||||
|
local source, om, si, si_props, si_flags, target =
|
||||||
|
putils:unwrap_find_target_event (event)
|
||||||
|
|
||||||
-- bypass the hook, nothing to link to
|
if not target then
|
||||||
if not target then
|
-- bypass the hook, nothing to link to.
|
||||||
return
|
transition:advance ()
|
||||||
end
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local target_props = target.properties
|
local target_props = target.properties
|
||||||
local out_item = nil
|
local out_item = nil
|
||||||
local in_item = nil
|
local in_item = nil
|
||||||
local si_link = nil
|
local si_link = nil
|
||||||
local passthrough = si_flags.can_passthrough
|
local passthrough = si_flags.can_passthrough
|
||||||
|
|
||||||
Log.info (si, string.format ("handling item: %s (%s)",
|
Log.info (si, string.format ("handling item: %s (%s)",
|
||||||
tostring (si_props ["node.name"]), tostring (si_props ["node.id"])))
|
tostring (si_props ["node.name"]), tostring (si_props ["node.id"])))
|
||||||
|
|
||||||
local exclusive = cutils.parseBool (si_props ["node.exclusive"])
|
local exclusive = cutils.parseBool (si_props ["node.exclusive"])
|
||||||
local passive = cutils.parseBool (si_props ["node.passive"]) or
|
local passive = cutils.parseBool (si_props ["node.passive"]) or
|
||||||
cutils.parseBool (target_props ["node.passive"])
|
cutils.parseBool (target_props ["node.passive"])
|
||||||
|
|
||||||
-- break rescan if tried more than 5 times with same target
|
-- break rescan if tried more than 5 times with same target
|
||||||
if si_flags.failed_peer_id ~= nil and
|
if si_flags.failed_peer_id ~= nil and
|
||||||
si_flags.failed_peer_id == target.id and
|
si_flags.failed_peer_id == target.id and
|
||||||
si_flags.failed_count ~= nil and
|
si_flags.failed_count ~= nil and
|
||||||
si_flags.failed_count > 5 then
|
si_flags.failed_count > 5 then
|
||||||
Log.warning (si, "tried to link on last rescan, not retrying")
|
transition:return_error ("tried to link on last rescan, not retrying "
|
||||||
goto done
|
.. tostring (si_link))
|
||||||
end
|
end
|
||||||
|
|
||||||
if si_props ["item.node.direction"] == "output" then
|
if si_props ["item.node.direction"] == "output" then
|
||||||
-- playback
|
-- playback
|
||||||
out_item = si
|
out_item = si
|
||||||
in_item = target
|
in_item = target
|
||||||
else
|
else
|
||||||
-- capture
|
-- capture
|
||||||
in_item = si
|
in_item = si
|
||||||
out_item = target
|
out_item = target
|
||||||
end
|
end
|
||||||
|
|
||||||
Log.info (si,
|
Log.info (si,
|
||||||
string.format ("link %s <-> %s passive:%s, passthrough:%s, exclusive:%s",
|
string.format ("link %s <-> %s passive:%s, passthrough:%s, exclusive:%s",
|
||||||
tostring (si_props ["node.name"]),
|
tostring (si_props ["node.name"]),
|
||||||
tostring (target_props ["node.name"]),
|
tostring (target_props ["node.name"]),
|
||||||
tostring (passive), tostring (passthrough), tostring (exclusive)))
|
tostring (passive), tostring (passthrough), tostring (exclusive)))
|
||||||
|
|
||||||
-- create and configure link
|
-- create and configure link
|
||||||
si_link = SessionItem ("si-standard-link")
|
si_link = SessionItem ("si-standard-link")
|
||||||
if not si_link:configure {
|
if not si_link:configure {
|
||||||
["out.item"] = out_item,
|
["out.item"] = out_item,
|
||||||
["in.item"] = in_item,
|
["in.item"] = in_item,
|
||||||
["passive"] = passive,
|
["passive"] = passive,
|
||||||
["passthrough"] = passthrough,
|
["passthrough"] = passthrough,
|
||||||
["exclusive"] = exclusive,
|
["exclusive"] = exclusive,
|
||||||
["out.item.port.context"] = "output",
|
["out.item.port.context"] = "output",
|
||||||
["in.item.port.context"] = "input",
|
["in.item.port.context"] = "input",
|
||||||
["is.policy.item.link"] = true,
|
["is.policy.item.link"] = true,
|
||||||
} then
|
} then
|
||||||
Log.warning (si_link, "failed to configure si-standard-link")
|
transition:return_error ("failed to configure si-standard-link "
|
||||||
goto done
|
.. tostring (si_link))
|
||||||
end
|
return
|
||||||
|
end
|
||||||
|
|
||||||
si_link:connect("link-error", function (_, error_msg)
|
si_link:connect("link-error", function (_, error_msg)
|
||||||
local ids = {si.id, si_flags.peer_id}
|
local ids = {si.id, si_flags.peer_id}
|
||||||
|
|
||||||
for _, id in ipairs (ids) do
|
for _, id in ipairs (ids) do
|
||||||
local si = om:lookup {
|
local si = om:lookup {
|
||||||
Constraint { "id", "=", id, type = "gobject" },
|
Constraint { "id", "=", id, type = "gobject" },
|
||||||
}
|
|
||||||
if si then
|
|
||||||
local node = si:get_associated_proxy ("node")
|
|
||||||
local client_id = node.properties["client.id"]
|
|
||||||
if client_id then
|
|
||||||
local client = om:lookup {
|
|
||||||
Constraint { "bound-id", "=", client_id, type = "gobject" }
|
|
||||||
}
|
}
|
||||||
if client then
|
if si then
|
||||||
Log.info (node, "sending client error: " .. error_msg)
|
local node = si:get_associated_proxy ("node")
|
||||||
client:send_error (node["bound-id"], -32, error_msg)
|
local client_id = node.properties["client.id"]
|
||||||
|
if client_id then
|
||||||
|
local client = om:lookup {
|
||||||
|
Constraint { "bound-id", "=", client_id, type = "gobject" }
|
||||||
|
}
|
||||||
|
if client then
|
||||||
|
Log.info (node, "sending client error: " .. error_msg)
|
||||||
|
client:send_error (node["bound-id"], -32, error_msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- register
|
-- register
|
||||||
si_flags.peer_id = target.id
|
si_flags.peer_id = target.id
|
||||||
si_flags.failed_peer_id = target.id
|
si_flags.failed_peer_id = target.id
|
||||||
if si_flags.failed_count ~= nil then
|
if si_flags.failed_count ~= nil then
|
||||||
si_flags.failed_count = si_flags.failed_count + 1
|
si_flags.failed_count = si_flags.failed_count + 1
|
||||||
else
|
else
|
||||||
si_flags.failed_count = 1
|
si_flags.failed_count = 1
|
||||||
end
|
|
||||||
si_link:register ()
|
|
||||||
|
|
||||||
-- activate
|
|
||||||
si_link:activate (Feature.SessionItem.ACTIVE, function (l, e)
|
|
||||||
if e then
|
|
||||||
Log.info (l, "failed to activate si-standard-link: " .. tostring (si) .. " error:" .. tostring (e))
|
|
||||||
if si_flags ~= nil then
|
|
||||||
si_flags.peer_id = nil
|
|
||||||
end
|
end
|
||||||
l:remove ()
|
si_link:register ()
|
||||||
else
|
|
||||||
|
-- activate
|
||||||
|
si_link:activate (Feature.SessionItem.ACTIVE, function (l, e)
|
||||||
|
if e then
|
||||||
|
transition:return_error ("failed to activate si-standard-link: "
|
||||||
|
.. tostring (si) .. " error:" .. tostring (e))
|
||||||
|
if si_flags ~= nil then
|
||||||
|
si_flags.peer_id = nil
|
||||||
|
end
|
||||||
|
l:remove ()
|
||||||
|
else
|
||||||
|
si_flags.si_link = si_link
|
||||||
|
transition:advance ()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
link_activated = {
|
||||||
|
next = "none",
|
||||||
|
execute = function (event, transition)
|
||||||
|
local source, om, si, si_props, si_flags, target =
|
||||||
|
putils:unwrap_find_target_event (event)
|
||||||
|
if not target then
|
||||||
|
-- bypass the hook, nothing to link to.
|
||||||
|
transition:advance ()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if si_flags ~= nil then
|
if si_flags ~= nil then
|
||||||
si_flags.failed_peer_id = nil
|
si_flags.failed_peer_id = nil
|
||||||
if si_flags.peer_id == nil then
|
if si_flags.peer_id == nil then
|
||||||
si_flags.peer_id = target.id
|
si_flags.peer_id = si_target.id
|
||||||
end
|
end
|
||||||
si_flags.failed_count = 0
|
si_flags.failed_count = 0
|
||||||
end
|
end
|
||||||
Log.info (l, "activated si-standard-link " .. tostring (si))
|
Log.info (si_flags.si_link, "activated si-standard-link between "
|
||||||
end
|
.. tostring (si).." and "..tostring(si_target))
|
||||||
end)
|
|
||||||
|
|
||||||
::done::
|
transition:advance ()
|
||||||
si_flags.was_handled = true
|
end,
|
||||||
putils.checkFollowDefault (si, target, si_flags.has_node_defined_target)
|
},
|
||||||
end
|
},
|
||||||
}:register ()
|
}:register ()
|
||||||
|
Reference in New Issue
Block a user