From 6eaeb61d580c335d27568267fb873babdcec68c9 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Fri, 4 Feb 2022 12:04:16 +0100 Subject: [PATCH] os/session_policy.h: add 'with_matching_policy' This patch makes the server-side policy-matching logic available outside the 'Session_policy' class. Given that the new 'with_matching_policy' function does not throw any exception, it gives server implementations the freedom to avoid the C++ exception mechanism for the policy handling. --- repos/os/include/os/session_policy.h | 79 ++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/repos/os/include/os/session_policy.h b/repos/os/include/os/session_policy.h index 9885470640..7e0b58c6c8 100644 --- a/repos/os/include/os/session_policy.h +++ b/repos/os/include/os/session_policy.h @@ -23,6 +23,11 @@ namespace Genode { struct Xml_node_label_score; + + template + void with_matching_policy(String const &, Xml_node const &, + MATCH_FN const &, NO_MATCH_FN const &); + class Session_policy; } @@ -155,6 +160,49 @@ struct Genode::Xml_node_label_score }; +/** + * Call 'match_fn' with the policy that matches best the given 'label' + * + * \param policies XML node that contains potentially many '' + * nodes and an optional '' node. + * \param match_fn functor called with best matching policy XML node + * argmument + * \param no_match_fn functor called if no matching policy exists + */ +template +void Genode::with_matching_policy(String const &label, + Xml_node const &policies, + MATCH_FN const &match_fn, + NO_MATCH_FN const &no_match_fn) +{ + /* + * Find policy node that matches best + */ + Xml_node best_match(""); + Xml_node_label_score best_score; + + policies.for_each_sub_node("policy", [&] (Xml_node const &policy) { + + Xml_node_label_score const score(policy, label); + + if (score.stronger(best_score)) { + best_match = policy; + best_score = score; + } + }); + + /* fall back to default policy if no match exists */ + if (best_match.has_type("none")) + policies.with_sub_node("default-policy", [&] (Xml_node const &policy) { + best_match = policy; }); + + if (best_match.has_type("none")) + no_match_fn(); + else + match_fn(best_match); +} + + /** * Query server-side policy for a session request */ @@ -175,33 +223,18 @@ class Genode::Session_policy : public Xml_node template static Xml_node _query_policy(String const &label, Xml_node config) { - /* - * Find policy node that matches best - */ - Xml_node best_match(""); - Xml_node_label_score best_score; + Xml_node result(""); - /* - * Functor to be applied to each policy node - */ - auto lambda = [&] (Xml_node policy) { - Xml_node_label_score const score(policy, label); - if (score.stronger(best_score)) { - best_match = policy; - best_score = score; - } - }; + with_matching_policy(label, config, - config.for_each_sub_node("policy", lambda); + [&] (Xml_node const &policy) { + result = policy; }, - if (!best_match.has_type("none")) - return best_match; + [&] () { + warning("no policy defined for label '", label, "'"); + throw No_policy_defined(); }); - try { return config.sub_node("default-policy"); } - catch (...) { } - - warning("no policy defined for label '", label, "'"); - throw No_policy_defined(); + return result; } public: