mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
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:
parent
2d199982eb
commit
c0af463b81
@ -69,11 +69,38 @@ struct Genode::Child_policy
|
||||
* Determine service to provide a session request
|
||||
*
|
||||
* \return service to be contacted for the new session
|
||||
* \deprecated
|
||||
*
|
||||
* \throw Parent::Service_denied
|
||||
*/
|
||||
virtual Service &resolve_session_request(Service::Name const &,
|
||||
Session_state::Args const &) = 0;
|
||||
Session_state::Args const &)
|
||||
{
|
||||
throw Parent::Service_denied();
|
||||
}
|
||||
|
||||
/**
|
||||
* Routing destination of a session request
|
||||
*/
|
||||
struct Route
|
||||
{
|
||||
Service &service;
|
||||
Session_label const label;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine service and server-side label for a given session request
|
||||
*
|
||||
* \return routing and policy-selection information for the session
|
||||
*
|
||||
* \throw Parent::Service_denied
|
||||
*/
|
||||
virtual Route resolve_session_request(Service::Name const &,
|
||||
Session_label const &)
|
||||
{
|
||||
/* \deprecated make pure virtual once the old version is gone */
|
||||
throw Parent::Service_denied();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply transformations to session arguments
|
||||
@ -271,6 +298,9 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
typedef Session_state::Args Args;
|
||||
|
||||
static Child_policy::Route _resolve_session_request(Child_policy &,
|
||||
Service::Name const &,
|
||||
char const *);
|
||||
/*
|
||||
* Members that are initialized not before the child's environment is
|
||||
* complete.
|
||||
@ -370,7 +400,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
Args const _args;
|
||||
|
||||
Service &_service;
|
||||
Child_policy::Route _route;
|
||||
|
||||
/*
|
||||
* The 'Env_service' monitors session responses in order to attempt
|
||||
@ -439,8 +469,9 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
Label const &label = Label())
|
||||
:
|
||||
_args(_construct_args(child._policy, label)),
|
||||
_service(child._policy.resolve_session_request(_service_name(), _args)),
|
||||
_env_service(child, _service),
|
||||
_route(child._resolve_session_request(child._policy, _service_name(),
|
||||
_args.string())),
|
||||
_env_service(child, _route.service),
|
||||
_connection(_env_service, child._id_space, id, _args,
|
||||
child._policy.filter_session_affinity(Affinity()))
|
||||
{ }
|
||||
|
@ -60,8 +60,8 @@ struct Genode::Local_connection_base : Noncopyable
|
||||
Args const &args, Affinity const &affinity,
|
||||
size_t ram_quota)
|
||||
:
|
||||
_session_state(service, id_space, id, _init_args(args, ram_quota),
|
||||
affinity)
|
||||
_session_state(service, id_space, id, label_from_args(args.string()),
|
||||
_init_args(args, ram_quota), affinity)
|
||||
{
|
||||
_session_state.service().initiate_request(_session_state);
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ class Genode::Local_service : public Service
|
||||
case Session_state::CREATE_REQUESTED:
|
||||
|
||||
try {
|
||||
SESSION &rpc_obj = _factory.create(session.args(),
|
||||
SESSION &rpc_obj = _factory.create(Session_state::Server_args(session).string(),
|
||||
session.affinity());
|
||||
session.local_ptr = &rpc_obj;
|
||||
session.cap = rpc_obj.cap();
|
||||
@ -272,9 +272,10 @@ class Genode::Parent_service : public Service
|
||||
session.id_at_parent.construct(session.parent_client,
|
||||
_env.id_space());
|
||||
try {
|
||||
|
||||
session.cap = _env.session(name().string(),
|
||||
session.id_at_parent->id(),
|
||||
session.args().string(),
|
||||
Session_state::Server_args(session).string(),
|
||||
session.affinity());
|
||||
|
||||
session.phase = Session_state::AVAILABLE;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <base/id_space.h>
|
||||
#include <base/env.h>
|
||||
#include <base/log.h>
|
||||
#include <base/session_label.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
@ -62,6 +63,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
|
||||
|
||||
Reconstructible<Id_space<Parent::Client>::Element> _id_at_client;
|
||||
|
||||
Session_label const _label;
|
||||
Args _args;
|
||||
Affinity _affinity;
|
||||
|
||||
@ -110,15 +112,22 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
|
||||
* Constructor
|
||||
*
|
||||
* \param service interface that was used to create the session
|
||||
* \param label session label to be presented to the server
|
||||
* \param client_id_space ID space for client-side session IDs
|
||||
* \param client_id session ID picked by the client
|
||||
* \param args session arguments
|
||||
*
|
||||
* \throw Id_space<Parent::Client>::Conflicting_id
|
||||
*
|
||||
* The client-provided (and child-name-prefixed) session label is
|
||||
* contained in 'args'. In contrast, the 'label' argument is the label
|
||||
* presented to the server along with the session request, which
|
||||
* depends on the policy of 'Child_policy::resolve_session_request'.
|
||||
*/
|
||||
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);
|
||||
|
||||
@ -195,6 +204,24 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
|
||||
* This function has no effect for sessions not created via a 'Factory'.
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
/**
|
||||
* Utility to override the client-provided label by the label assigned
|
||||
* by 'Child_policy::resolve_session_request'.
|
||||
*/
|
||||
struct Server_args
|
||||
{
|
||||
char _buf[Args::capacity()];
|
||||
|
||||
Server_args(Session_state const &session)
|
||||
{
|
||||
Genode::strncpy(_buf, session._args.string(), sizeof(_buf));
|
||||
Arg_string::set_arg_string(_buf, sizeof(_buf),
|
||||
"label", session._label.string());
|
||||
}
|
||||
|
||||
char const *string() const { return _buf; }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -85,8 +85,8 @@ _ZN6Genode13Registry_base7_insertERNS0_7ElementE T
|
||||
_ZN6Genode13Registry_base7_removeERNS0_7ElementE T
|
||||
_ZN6Genode13Registry_base9_for_eachERNS0_15Untyped_functorE T
|
||||
_ZN6Genode13Session_state7destroyEv T
|
||||
_ZN6Genode13Session_stateC1ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_6StringILm256EEERKNS_8AffinityE T
|
||||
_ZN6Genode13Session_stateC2ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_6StringILm256EEERKNS_8AffinityE T
|
||||
_ZN6Genode13Session_stateC1ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelERKNS_6StringILm256EEERKNS_8AffinityE T
|
||||
_ZN6Genode13Session_stateC2ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelERKNS_6StringILm256EEERKNS_8AffinityE T
|
||||
_ZN6Genode13Shared_objectC1ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
|
||||
_ZN6Genode13Shared_objectC2ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
|
||||
_ZN6Genode13Shared_objectD1Ev T
|
||||
|
@ -94,7 +94,8 @@ Session_capability Core_parent::session(Parent::Client::Id id,
|
||||
return;
|
||||
|
||||
Session_state &session = *new (_alloc)
|
||||
Session_state(service, _id_space, id, args.string(), affinity);
|
||||
Session_state(service, _id_space, id, label_from_args(args.string()),
|
||||
args.string(), affinity);
|
||||
|
||||
service.initiate_request(session);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{ }
|
||||
|
Loading…
Reference in New Issue
Block a user