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
|
* Determine service to provide a session request
|
||||||
*
|
*
|
||||||
* \return service to be contacted for the new session
|
* \return service to be contacted for the new session
|
||||||
|
* \deprecated
|
||||||
*
|
*
|
||||||
* \throw Parent::Service_denied
|
* \throw Parent::Service_denied
|
||||||
*/
|
*/
|
||||||
virtual Service &resolve_session_request(Service::Name const &,
|
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
|
* Apply transformations to session arguments
|
||||||
@ -271,6 +298,9 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
|
|
||||||
typedef Session_state::Args Args;
|
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
|
* Members that are initialized not before the child's environment is
|
||||||
* complete.
|
* complete.
|
||||||
@ -370,7 +400,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
|
|
||||||
Args const _args;
|
Args const _args;
|
||||||
|
|
||||||
Service &_service;
|
Child_policy::Route _route;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 'Env_service' monitors session responses in order to attempt
|
* 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())
|
Label const &label = Label())
|
||||||
:
|
:
|
||||||
_args(_construct_args(child._policy, label)),
|
_args(_construct_args(child._policy, label)),
|
||||||
_service(child._policy.resolve_session_request(_service_name(), _args)),
|
_route(child._resolve_session_request(child._policy, _service_name(),
|
||||||
_env_service(child, _service),
|
_args.string())),
|
||||||
|
_env_service(child, _route.service),
|
||||||
_connection(_env_service, child._id_space, id, _args,
|
_connection(_env_service, child._id_space, id, _args,
|
||||||
child._policy.filter_session_affinity(Affinity()))
|
child._policy.filter_session_affinity(Affinity()))
|
||||||
{ }
|
{ }
|
||||||
|
@ -60,8 +60,8 @@ struct Genode::Local_connection_base : Noncopyable
|
|||||||
Args const &args, Affinity const &affinity,
|
Args const &args, Affinity const &affinity,
|
||||||
size_t ram_quota)
|
size_t ram_quota)
|
||||||
:
|
:
|
||||||
_session_state(service, id_space, id, _init_args(args, ram_quota),
|
_session_state(service, id_space, id, label_from_args(args.string()),
|
||||||
affinity)
|
_init_args(args, ram_quota), affinity)
|
||||||
{
|
{
|
||||||
_session_state.service().initiate_request(_session_state);
|
_session_state.service().initiate_request(_session_state);
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ class Genode::Local_service : public Service
|
|||||||
case Session_state::CREATE_REQUESTED:
|
case Session_state::CREATE_REQUESTED:
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SESSION &rpc_obj = _factory.create(session.args(),
|
SESSION &rpc_obj = _factory.create(Session_state::Server_args(session).string(),
|
||||||
session.affinity());
|
session.affinity());
|
||||||
session.local_ptr = &rpc_obj;
|
session.local_ptr = &rpc_obj;
|
||||||
session.cap = rpc_obj.cap();
|
session.cap = rpc_obj.cap();
|
||||||
@ -272,9 +272,10 @@ class Genode::Parent_service : public Service
|
|||||||
session.id_at_parent.construct(session.parent_client,
|
session.id_at_parent.construct(session.parent_client,
|
||||||
_env.id_space());
|
_env.id_space());
|
||||||
try {
|
try {
|
||||||
|
|
||||||
session.cap = _env.session(name().string(),
|
session.cap = _env.session(name().string(),
|
||||||
session.id_at_parent->id(),
|
session.id_at_parent->id(),
|
||||||
session.args().string(),
|
Session_state::Server_args(session).string(),
|
||||||
session.affinity());
|
session.affinity());
|
||||||
|
|
||||||
session.phase = Session_state::AVAILABLE;
|
session.phase = Session_state::AVAILABLE;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <base/id_space.h>
|
#include <base/id_space.h>
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
#include <base/session_label.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
|
|
||||||
@ -62,8 +63,9 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
|
|||||||
|
|
||||||
Reconstructible<Id_space<Parent::Client>::Element> _id_at_client;
|
Reconstructible<Id_space<Parent::Client>::Element> _id_at_client;
|
||||||
|
|
||||||
Args _args;
|
Session_label const _label;
|
||||||
Affinity _affinity;
|
Args _args;
|
||||||
|
Affinity _affinity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -110,15 +112,22 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
|
|||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* \param service interface that was used to create the session
|
* \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_space ID space for client-side session IDs
|
||||||
* \param client_id session ID picked by the client
|
* \param client_id session ID picked by the client
|
||||||
* \param args session arguments
|
* \param args session arguments
|
||||||
*
|
*
|
||||||
* \throw Id_space<Parent::Client>::Conflicting_id
|
* \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,
|
Session_state(Service &service,
|
||||||
Id_space<Parent::Client> &client_id_space,
|
Id_space<Parent::Client> &client_id_space,
|
||||||
Parent::Client::Id client_id,
|
Parent::Client::Id client_id,
|
||||||
|
Session_label const &label,
|
||||||
Args const &args,
|
Args const &args,
|
||||||
Affinity const &affinity);
|
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'.
|
* This function has no effect for sessions not created via a 'Factory'.
|
||||||
*/
|
*/
|
||||||
void destroy();
|
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_base7_removeERNS0_7ElementE T
|
||||||
_ZN6Genode13Registry_base9_for_eachERNS0_15Untyped_functorE T
|
_ZN6Genode13Registry_base9_for_eachERNS0_15Untyped_functorE T
|
||||||
_ZN6Genode13Session_state7destroyEv T
|
_ZN6Genode13Session_state7destroyEv T
|
||||||
_ZN6Genode13Session_stateC1ERNS_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_6StringILm256EEERKNS_8AffinityE T
|
_ZN6Genode13Session_stateC2ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelERKNS_6StringILm256EEERKNS_8AffinityE T
|
||||||
_ZN6Genode13Shared_objectC1ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
|
_ZN6Genode13Shared_objectC1ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
|
||||||
_ZN6Genode13Shared_objectC2ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
|
_ZN6Genode13Shared_objectC2ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
|
||||||
_ZN6Genode13Shared_objectD1Ev T
|
_ZN6Genode13Shared_objectD1Ev T
|
||||||
|
@ -94,7 +94,8 @@ Session_capability Core_parent::session(Parent::Client::Id id,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Session_state &session = *new (_alloc)
|
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);
|
service.initiate_request(session);
|
||||||
|
|
||||||
|
@ -156,12 +156,13 @@ void Child::session_sigh(Signal_context_capability sigh)
|
|||||||
*/
|
*/
|
||||||
Session_state &
|
Session_state &
|
||||||
create_session(Child_policy::Name const &child_name, Service &service,
|
create_session(Child_policy::Name const &child_name, Service &service,
|
||||||
|
Session_label const &label,
|
||||||
Session_state::Factory &factory, Id_space<Parent::Client> &id_space,
|
Session_state::Factory &factory, Id_space<Parent::Client> &id_space,
|
||||||
Parent::Client::Id id, Session_state::Args const &args,
|
Parent::Client::Id id, Session_state::Args const &args,
|
||||||
Affinity const &affinity)
|
Affinity const &affinity)
|
||||||
{
|
{
|
||||||
try {
|
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) {
|
catch (Allocator::Out_of_memory) {
|
||||||
error("could not allocate session meta data for child ", child_name);
|
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,
|
Session_capability Child::session(Parent::Client::Id id,
|
||||||
Parent::Service_name const &name,
|
Parent::Service_name const &name,
|
||||||
Parent::Session_args const &args,
|
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);
|
Affinity const filtered_affinity = _policy.filter_session_affinity(affinity);
|
||||||
|
|
||||||
/* may throw a 'Parent::Service_denied' exception */
|
/* 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 =
|
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);
|
_id_space, id, argbuf, filtered_affinity);
|
||||||
|
|
||||||
session.ready_callback = this;
|
session.ready_callback = this;
|
||||||
|
@ -40,8 +40,9 @@ void Session_state::generate_session_request(Xml_generator &xml) const
|
|||||||
xml.node("create", [&] () {
|
xml.node("create", [&] () {
|
||||||
xml.attribute("id", id_at_server->id().value);
|
xml.attribute("id", id_at_server->id().value);
|
||||||
xml.attribute("service", _service.name());
|
xml.attribute("service", _service.name());
|
||||||
|
xml.attribute("label", _label);
|
||||||
xml.node("args", [&] () {
|
xml.node("args", [&] () {
|
||||||
xml.append_sanitized(_args.string());
|
xml.append_sanitized(Server_args(*this).string());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -110,11 +111,12 @@ void Session_state::destroy()
|
|||||||
Session_state::Session_state(Service &service,
|
Session_state::Session_state(Service &service,
|
||||||
Id_space<Parent::Client> &client_id_space,
|
Id_space<Parent::Client> &client_id_space,
|
||||||
Parent::Client::Id client_id,
|
Parent::Client::Id client_id,
|
||||||
|
Session_label const &label,
|
||||||
Args const &args,
|
Args const &args,
|
||||||
Affinity const &affinity)
|
Affinity const &affinity)
|
||||||
:
|
:
|
||||||
_service(service),
|
_service(service),
|
||||||
_donated_ram_quota(Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0)),
|
_donated_ram_quota(Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0)),
|
||||||
_id_at_client(*this, client_id_space, client_id),
|
_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