monitor/sandbox: use Callable

Issue #5420
This commit is contained in:
Norman Feske 2025-01-15 15:40:02 +01:00 committed by Christian Helmuth
parent 414afba682
commit 33446be8ac
6 changed files with 49 additions and 114 deletions

View File

@ -15,6 +15,7 @@
#define _INCLUDE__SANDBOX__SANDBOX_H_
#include <util/xml_node.h>
#include <util/callable.h>
#include <util/noncopyable.h>
#include <base/registry.h>
#include <base/service.h>
@ -60,12 +61,13 @@ class Genode::Sandbox : Noncopyable
Region_map &address_space;
};
struct Fn : Interface { virtual void call(Intrinsics &) const = 0; };
using With_intrinsics = Callable<void, Intrinsics &>;
/**
* Call 'Fn' with the 'Intrinsics' that apply for the specified PD
* Call 'fn' with the 'Intrinsics' that apply for the specified PD
*/
virtual void with_intrinsics(Capability<Pd_session>, Pd_session &, Fn const &) = 0;
virtual void with_intrinsics(Capability<Pd_session>, Pd_session &,
With_intrinsics::Ft const &fn) = 0;
/**
* Start the initial thread of new PD at the given instruction pointer
@ -207,26 +209,13 @@ class Genode::Sandbox::Local_service_base : public Service
using Resources = Session::Resources;
struct Request_fn : Interface
{
virtual void with_requested_session(Request &) = 0;
};
using With_request = Callable<void, Request &>;
using With_upgrade = Callable<Upgrade_response, Session &, Resources const &>;
using With_close = Callable<Close_response, Session &>;
void _for_each_requested_session(Request_fn &);
struct Upgrade_fn : Interface
{
virtual Upgrade_response with_upgraded_session(Session &, Resources) = 0;
};
void _for_each_upgraded_session(Upgrade_fn &);
struct Close_fn : Interface
{
virtual Close_response close_session(Session &) = 0;
};
void _for_each_session_to_close(Close_fn &);
void _for_each_requested_session(With_request::Ft const &);
void _for_each_upgraded_session (With_upgrade::Ft const &);
void _for_each_session_to_close (With_close::Ft const &);
Id_space<Parent::Server> _server_id_space { };
@ -253,21 +242,9 @@ struct Genode::Sandbox::Local_service : private Local_service_base
* ('resources', 'label', 'diag') and allows the caller to respond
* to the session request ('deliver_session', 'deny').
*/
template <typename FN>
void for_each_requested_session(FN const &fn)
void for_each_requested_session(auto const &fn)
{
struct Untyped_fn : Local_service_base::Request_fn
{
FN const &_fn;
Untyped_fn(FN const &fn) : _fn(fn) { }
void with_requested_session(Request &request) override
{
_fn(request);
}
} untyped_fn(fn);
_for_each_requested_session(untyped_fn);
_for_each_requested_session(With_request::Fn { fn });
}
/**
@ -279,22 +256,11 @@ struct Genode::Sandbox::Local_service : private Local_service_base
*
* The functor must return an 'Upgrade_response'.
*/
template <typename FN>
void for_each_upgraded_session(FN const &fn)
void for_each_upgraded_session(auto const &fn)
{
struct Untyped_fn : Local_service_base::Upgrade_fn
{
FN const &_fn;
Untyped_fn(FN const &fn) : _fn(fn) { }
Upgrade_response with_upgraded_session(Session &session,
Resources resources) override
{
return _fn(static_cast<ST &>(session), resources);
}
} untyped_fn(fn);
_for_each_upgraded_session(untyped_fn);
_for_each_upgraded_session(With_upgrade::Fn {
[&] (Session &session, Resources const &resources) {
return fn(static_cast<ST &>(session), resources); } });
}
/**
@ -303,21 +269,11 @@ struct Genode::Sandbox::Local_service : private Local_service_base
* The functor is called with a reference to the session object (type
* 'ST') as argument and must return a 'Close_response'.
*/
template <typename FN>
void for_each_session_to_close(FN const &fn)
void for_each_session_to_close(auto const &fn)
{
struct Untyped_fn : Local_service_base::Close_fn
{
FN const &_fn;
Untyped_fn(FN const &fn) : _fn(fn) { }
Close_response close_session(Session &session) override
{
return _fn(static_cast<ST &>(session));
}
} untyped_fn(fn);
_for_each_session_to_close(untyped_fn);
_for_each_session_to_close(With_close::Fn {
[&] (Session &session) {
return fn(static_cast<ST &>(session)); } });
}
};

View File

@ -1,7 +1,7 @@
_ZN6Genode7Sandbox12apply_configERKNS_8Xml_nodeE T
_ZN6Genode7Sandbox18Local_service_base26_for_each_session_to_closeERNS1_8Close_fnE T
_ZN6Genode7Sandbox18Local_service_base26_for_each_upgraded_sessionERNS1_10Upgrade_fnE T
_ZN6Genode7Sandbox18Local_service_base27_for_each_requested_sessionERNS1_10Request_fnE T
_ZN6Genode7Sandbox18Local_service_base26_for_each_session_to_closeERKNS_8CallableINS1_14Close_responseEJRNS_7SessionEEE2FtE T
_ZN6Genode7Sandbox18Local_service_base26_for_each_upgraded_sessionERKNS_8CallableINS1_16Upgrade_responseEJRNS_7SessionERKNS4_9ResourcesEEE2FtE T
_ZN6Genode7Sandbox18Local_service_base27_for_each_requested_sessionERKNS_8CallableIvJRNS1_7RequestEEE2FtE T
_ZN6Genode7Sandbox18Local_service_baseC1ERS0_RKNS_6StringILm32EEERNS1_6WakeupE T
_ZN6Genode7Sandbox18Local_service_baseC2ERS0_RKNS_6StringILm32EEERNS1_6WakeupE T
_ZN6Genode7SandboxC1ERNS_3EnvERNS0_13State_handlerE T

View File

@ -74,27 +74,14 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
enum class Sample_state_result { CHANGED, UNCHANGED };
/*
* Helper for passing lambda functions as 'Pd_intrinsics::Fn'
*/
using Pd_intrinsics = Genode::Sandbox::Pd_intrinsics;
template <typename PD_SESSION, typename FN>
template <typename PD_SESSION>
static void with_pd_intrinsics(Pd_intrinsics &pd_intrinsics,
Capability<Pd_session> cap, PD_SESSION &pd,
FN const &fn)
auto const &fn)
{
struct Impl : Pd_intrinsics::Fn
{
using Intrinsics = Pd_intrinsics::Intrinsics;
FN const &_fn;
Impl(FN const &fn) : _fn(fn) { }
void call(Intrinsics &intrinsics) const override { _fn(intrinsics); }
};
pd_intrinsics.with_intrinsics(cap, pd, Impl { fn });
pd_intrinsics.with_intrinsics(cap, pd, Pd_intrinsics::With_intrinsics::Fn { fn });
}
private:
@ -306,8 +293,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Pd_intrinsics &_pd_intrinsics;
template <typename FN>
void _with_pd_intrinsics(FN const &fn)
void _with_pd_intrinsics(auto const &fn)
{
with_pd_intrinsics(_pd_intrinsics, _child.pd_session_cap(), _child.pd(), fn);
}

View File

@ -259,13 +259,14 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
{
Env &_env;
void with_intrinsics(Capability<Pd_session>, Pd_session &pd, Fn const &fn) override
void with_intrinsics(Capability<Pd_session>, Pd_session &pd,
With_intrinsics::Ft const &fn) override
{
Region_map_client region_map(pd.address_space());
Intrinsics intrinsics { _env.pd(), _env.pd_session_cap(),
_env.cpu(), _env.cpu_session_cap(), region_map };
fn.call(intrinsics);
fn(intrinsics);
}
void start_initial_thread(Capability<Cpu_thread> cap, addr_t ip) override
@ -520,7 +521,7 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
** Sandbox::Local_service_base **
*********************************/
void Genode::Sandbox::Local_service_base::_for_each_requested_session(Request_fn &fn)
void Genode::Sandbox::Local_service_base::_for_each_requested_session(With_request::Ft const &fn)
{
_server_id_space.for_each<Session_state>([&] (Session_state &session) {
@ -528,7 +529,7 @@ void Genode::Sandbox::Local_service_base::_for_each_requested_session(Request_fn
Request request(session);
fn.with_requested_session(request);
fn(request);
bool wakeup_client = false;
@ -551,7 +552,7 @@ void Genode::Sandbox::Local_service_base::_for_each_requested_session(Request_fn
}
void Genode::Sandbox::Local_service_base::_for_each_upgraded_session(Upgrade_fn &fn)
void Genode::Sandbox::Local_service_base::_for_each_upgraded_session(With_upgrade::Ft const &fn)
{
_server_id_space.for_each<Session_state>([&] (Session_state &session) {
@ -566,7 +567,7 @@ void Genode::Sandbox::Local_service_base::_for_each_upgraded_session(Upgrade_fn
Session::Resources const amount { session.ram_upgrade,
session.cap_upgrade };
switch (fn.with_upgraded_session(*session.local_ptr, amount)) {
switch (fn(*session.local_ptr, amount)) {
case Upgrade_response::CONFIRMED:
session.phase = Session_state::CAP_HANDED_OUT;
@ -583,7 +584,7 @@ void Genode::Sandbox::Local_service_base::_for_each_upgraded_session(Upgrade_fn
}
void Genode::Sandbox::Local_service_base::_for_each_session_to_close(Close_fn &close_fn)
void Genode::Sandbox::Local_service_base::_for_each_session_to_close(With_close::Ft const &fn)
{
/*
* Collection of closed sessions to be destructed via callback
@ -605,7 +606,7 @@ void Genode::Sandbox::Local_service_base::_for_each_session_to_close(Close_fn &c
if (session.local_ptr == nullptr)
return;
switch (close_fn.close_session(*session.local_ptr)) {
switch (fn(*session.local_ptr)) {
case Close_response::CLOSED:

View File

@ -14,6 +14,7 @@
#ifndef _GDB_COMMAND_H_
#define _GDB_COMMAND_H_
#include <util/callable.h>
#include <base/registry.h>
#include <monitor/string.h>
#include <types.h>
@ -47,23 +48,13 @@ struct Monitor::Gdb::Command : private Commands::Element, Interface
with_skipped_prefix(bytes, name, match_remainder_fn);
}
struct With_args_fn : Interface
{
virtual void call(Const_byte_range_ptr const &args) const = 0;
};
using With_args = Callable<void, Const_byte_range_ptr const &>;
virtual void _with_args(Const_byte_range_ptr const &, With_args_fn const &) const = 0;
virtual void _with_args(Const_byte_range_ptr const &, With_args::Ft const &) const = 0;
void with_args(Const_byte_range_ptr const &command_bytes, auto const &fn) const
{
using Fn = typeof(fn);
struct Impl : With_args_fn
{
Fn const &_fn;
Impl(Fn const &fn) : _fn(fn) { }
void call(Const_byte_range_ptr const &args) const override { _fn(args); }
};
_with_args(command_bytes, Impl(fn));
_with_args(command_bytes, With_args::Fn { fn });
}
virtual void execute(State &, Const_byte_range_ptr const &args, Output &) const = 0;
@ -190,11 +181,11 @@ struct Monitor::Gdb::Command_with_separator : Command
}
void _with_args(Const_byte_range_ptr const &bytes,
With_args_fn const &fn) const override
With_args::Ft const &fn) const override
{
_match_name(bytes, [&] (Const_byte_range_ptr const &bytes) {
_match_separator(bytes, [&] (Const_byte_range_ptr const &args) {
fn.call(args); }); });
fn(args); }); });
}
};
@ -204,10 +195,10 @@ struct Monitor::Gdb::Command_without_separator : Command
using Command::Command;
void _with_args(Const_byte_range_ptr const &bytes,
With_args_fn const &fn) const override
With_args::Ft const &fn) const override
{
_match_name(bytes, [&] (Const_byte_range_ptr const &args) {
fn.call(args); });
fn(args); });
}
};

View File

@ -86,7 +86,8 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics
} _monitored_ref_cpu { _env.ep(), _env.cpu_session_cap(), Session::Label { } };
void with_intrinsics(Capability<Pd_session> pd_cap, Pd_session &pd, Fn const &fn) override
void with_intrinsics(Capability<Pd_session> pd_cap, Pd_session &pd,
With_intrinsics::Ft const &fn) override
{
/*
* Depending on the presence of the PD session in our local entrypoint,
@ -111,7 +112,7 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics
.ref_cpu = _monitored_ref_cpu,
.ref_cpu_cap = _monitored_ref_cpu.cap(),
.address_space = inferior_pd._address_space };
fn.call(intrinsics);
fn(intrinsics);
},
[&] /* PD session not intercepted */ {
@ -122,7 +123,7 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics
.ref_cpu = _env.cpu(),
.ref_cpu_cap = _env.cpu_session_cap(),
.address_space = region_map };
fn.call(intrinsics);
fn(intrinsics);
}
);
}