base: Add Child_policy::Route

The new return value of 'resolve_session_request' allows the child
policy to define the label used as the policy selector at the server.

Because this patch introduces the distinction of the child-provided
label from the label as presented to the server along with the session
request, the latter is now handled as a dedicated 'Session_state'
argument.

Issue #2248
This commit is contained in:
Norman Feske
2017-02-14 17:38:09 +01:00
committed by Christian Helmuth
parent 2d199982eb
commit c0af463b81
8 changed files with 110 additions and 18 deletions

View File

@ -156,12 +156,13 @@ void Child::session_sigh(Signal_context_capability sigh)
*/
Session_state &
create_session(Child_policy::Name const &child_name, Service &service,
Session_label const &label,
Session_state::Factory &factory, Id_space<Parent::Client> &id_space,
Parent::Client::Id id, Session_state::Args const &args,
Affinity const &affinity)
{
try {
return service.create_session(factory, id_space, id, args, affinity);
return service.create_session(factory, id_space, id, label, args, affinity);
}
catch (Allocator::Out_of_memory) {
error("could not allocate session meta data for child ", child_name);
@ -179,6 +180,34 @@ create_session(Child_policy::Name const &child_name, Service &service,
}
/*
* \deprecated Temporary wrapper around 'Child_policy::resolve_session_request'
* that tries both overloads.
*
* \throw Parent::Service_denied
*/
Child_policy::Route Child::_resolve_session_request(Child_policy &policy,
Service::Name const &name,
char const *argbuf)
{
Session_label const label = label_from_args(argbuf);
/*
* \deprecated Try old interface, remove once all 'Child_policy'
* implementations are updated.
*/
try {
Session_state::Args args(argbuf);
return Child_policy::Route {
policy.resolve_session_request(name, args), label };
}
catch (Parent::Service_denied) { }
return policy.resolve_session_request(name, label);
}
Session_capability Child::session(Parent::Client::Id id,
Parent::Service_name const &name,
Parent::Session_args const &args,
@ -202,10 +231,11 @@ Session_capability Child::session(Parent::Client::Id id,
Affinity const filtered_affinity = _policy.filter_session_affinity(affinity);
/* may throw a 'Parent::Service_denied' exception */
Service &service = _policy.resolve_session_request(name.string(), argbuf);
Child_policy::Route route = _resolve_session_request(_policy, name.string(), argbuf);
Service &service = route.service;
Session_state &session =
create_session(_policy.name(), service, *_session_factory,
create_session(_policy.name(), service, route.label, *_session_factory,
_id_space, id, argbuf, filtered_affinity);
session.ready_callback = this;

View File

@ -40,8 +40,9 @@ void Session_state::generate_session_request(Xml_generator &xml) const
xml.node("create", [&] () {
xml.attribute("id", id_at_server->id().value);
xml.attribute("service", _service.name());
xml.attribute("label", _label);
xml.node("args", [&] () {
xml.append_sanitized(_args.string());
xml.append_sanitized(Server_args(*this).string());
});
});
break;
@ -110,11 +111,12 @@ void Session_state::destroy()
Session_state::Session_state(Service &service,
Id_space<Parent::Client> &client_id_space,
Parent::Client::Id client_id,
Session_label const &label,
Args const &args,
Affinity const &affinity)
:
_service(service),
_donated_ram_quota(Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0)),
_id_at_client(*this, client_id_space, client_id),
_args(args), _affinity(affinity)
_label(label), _args(args), _affinity(affinity)
{ }