Adapt low-level components to new parent interface

This patch adjusts the components of the os repository as well as device
drivers to the new parent interface.

Issue #2120
This commit is contained in:
Norman Feske
2016-11-06 14:27:26 +01:00
committed by Christian Helmuth
parent cfdbccc5c2
commit 8bafb9d41b
50 changed files with 1764 additions and 1964 deletions

View File

@ -3,3 +3,10 @@ subsystems via a session interface. The resources for the new subsystem are
provided by the client when opening the session. The client has no control over
the functioning of the subsystem except for the controlling the lifetime of the
subsystem.
By default, the loaded subsystem can access only those ROM modules that were
loaded into the loader session by the loader client. However, it is possible
to define a whitelist of ROM modules to be obtained from the loader's parent.
For an example, refer to the example 'run/loader.run' script.

View File

@ -29,150 +29,100 @@ namespace Loader {
using namespace Genode;
typedef Registered<Parent_service> Parent_service;
typedef Registry<Parent_service> Parent_services;
class Child : public Child_policy
{
private:
typedef String<Session::Name::MAX_SIZE> Label;
Env &_env;
Label _label;
Session_label const _label;
Name const _binary_name;
Rpc_entrypoint &_ep;
size_t const _ram_quota;
struct Resources
{
Pd_connection pd;
Ram_connection ram;
Cpu_connection cpu;
Parent_services &_parent_services;
Resources(char const *label,
Ram_session_client &ram_session_client,
size_t ram_quota,
Signal_context_capability fault_sigh)
: pd(label), ram(label), cpu(label)
{
/* deduce session costs from usable ram quota */
size_t session_donations = Cpu_connection::RAM_QUOTA +
Ram_connection::RAM_QUOTA;
if (ram_quota > session_donations)
ram_quota -= session_donations;
else ram_quota = 0;
ram.ref_account(ram_session_client);
ram_session_client.transfer_quota(ram.cap(), ram_quota);
/*
* Install CPU exception and RM fault handler assigned by
* the loader client via 'Loader_session::fault_handler'.
*/
cpu.exception_sigh(fault_sigh);
Region_map_client address_space(pd.address_space());
address_space.fault_handler(fault_sigh);
}
} _resources;
Genode::Child::Initial_thread _initial_thread { _resources.cpu,
_resources.pd,
_label.string() };
Region_map_client _address_space { _resources.pd.address_space() };
Service_registry &_parent_services;
Service &_local_nitpicker_service;
Service &_local_rom_service;
Service &_local_cpu_service;
Service &_local_pd_service;
Rom_session_client _binary_rom_session;
Init::Child_policy_provide_rom_file _binary_policy;
Init::Child_policy_enforce_labeling _labeling_policy;
Genode::Child _child;
Rom_session_capability _rom_session(char const *name)
{
try {
char args[Session::Name::MAX_SIZE];
snprintf(args, sizeof(args), "ram_quota=4K, label=\"%s\"", name);
return static_cap_cast<Rom_session>(_local_rom_service.session(args, Affinity()));
} catch (Genode::Parent::Service_denied) {
Genode::error("Lookup for ROM module \"", name, "\" failed");
throw;
}
}
public:
Child(char const *binary_name,
char const *label,
Dataspace_capability ldso_ds,
Rpc_entrypoint &ep,
Ram_session_client &ram_session_client,
Child(Env &env,
Name const &binary_name,
Session_label const &label,
size_t ram_quota,
Service_registry &parent_services,
Parent_services &parent_services,
Service &local_rom_service,
Service &local_cpu_service,
Service &local_pd_service,
Service &local_nitpicker_service,
Signal_context_capability fault_sigh)
:
_env(env),
_label(label),
_ep(ep),
_resources(_label.string(), ram_session_client, ram_quota, fault_sigh),
_binary_name(binary_name),
_ram_quota(Genode::Child::effective_ram_quota(ram_quota)),
_parent_services(parent_services),
_local_nitpicker_service(local_nitpicker_service),
_local_rom_service(local_rom_service),
_local_cpu_service(local_cpu_service),
_local_pd_service(local_pd_service),
_binary_rom_session(_rom_session(binary_name)),
_binary_policy("binary", _binary_rom_session.dataspace(), &_ep),
_labeling_policy(_label.string()),
_child(_binary_rom_session.dataspace(), ldso_ds,
_resources.pd, _resources.pd,
_resources.ram, _resources.ram,
_resources.cpu, _initial_thread,
*env()->rm_session(), _address_space, _ep, *this)
_child(_env.rm(), _env.ep().rpc_ep(), *this)
{ }
~Child()
{
_local_rom_service.close(_binary_rom_session);
}
~Child() { }
/****************************
** Child-policy interface **
****************************/
char const *name() const override { return _label.string(); }
Name name() const override { return _label; }
void filter_session_args(char const *service, char *args, size_t args_len) override
Binary_name binary_name() const override { return _binary_name; }
Ram_session &ref_ram() override { return _env.ram(); }
Ram_session_capability ref_ram_cap() const override { return _env.ram_session_cap(); }
void init(Ram_session &ram, Ram_session_capability ram_cap) override
{
_labeling_policy.filter_session_args(service, args, args_len);
ram.ref_account(ref_ram_cap());
ref_ram().transfer_quota(ram_cap, _ram_quota);
}
Service *resolve_session_request(const char *name,
const char *args) override
void filter_session_args(Service::Name const &service, char *args, size_t args_len) override
{
Service *service = 0;
_labeling_policy.filter_session_args(service.string(), args, args_len);
}
if ((service = _binary_policy.resolve_session_request(name, args)))
return service;
if (!strcmp(name, "Nitpicker")) return &_local_nitpicker_service;
if (!strcmp(name, "ROM")) return &_local_rom_service;
if (!strcmp(name, "CPU")) return &_local_cpu_service;
if (!strcmp(name, "PD")) return &_local_pd_service;
Service &resolve_session_request(Service::Name const &name,
Session_state::Args const &args) override
{
if (name == "Nitpicker") return _local_nitpicker_service;
if (name == "ROM") return _local_rom_service;
if (name == "CPU") return _local_cpu_service;
if (name == "PD") return _local_pd_service;
/* populate session-local parent service registry on demand */
service = _parent_services.find(name);
if (!service) {
service = new (env()->heap()) Parent_service(name);
_parent_services.insert(service);
}
return service;
Service *service = nullptr;
_parent_services.for_each([&] (Parent_service &s) {
if (s.name() == name)
service = &s; });
if (service)
return *service;
return *new (env()->heap()) Parent_service(_parent_services, name);
}
};
}

View File

@ -12,14 +12,13 @@
*/
/* Genode includes */
#include <base/env.h>
#include <base/component.h>
#include <base/heap.h>
#include <base/rpc_server.h>
#include <base/signal.h>
#include <base/sleep.h>
#include <loader_session/loader_session.h>
#include <cap_session/connection.h>
#include <root/component.h>
#include <os/session_policy.h>
/* local includes */
#include <child.h>
@ -41,104 +40,79 @@ class Loader::Session_component : public Rpc_object<Session>
{
private:
struct Local_rom_service : Service
struct Local_rom_factory : Local_service<Rom_session_component>::Factory
{
Rpc_entrypoint &_ep;
Entrypoint &_ep;
Allocator &_md_alloc;
Parent_service _parent_rom_service;
Rom_module_registry &_rom_modules;
Lock _lock;
List<Rom_session_component> _rom_sessions;
void _close(Rom_session_component *rom)
void _close(Rom_session_component &rom)
{
_rom_sessions.remove(rom);
destroy(&_md_alloc, rom);
_rom_sessions.remove(&rom);
Genode::destroy(_md_alloc, &rom);
}
Local_rom_service(Rpc_entrypoint &ep,
Local_rom_factory(Entrypoint &ep,
Allocator &md_alloc,
Rom_module_registry &rom_modules)
:
Service("virtual_rom"),
_ep(ep),
_md_alloc(md_alloc),
_parent_rom_service(Rom_session::service_name()),
_rom_modules(rom_modules)
_ep(ep), _md_alloc(md_alloc), _rom_modules(rom_modules)
{ }
~Local_rom_service()
~Local_rom_factory()
{
Lock::Guard guard(_lock);
while (_rom_sessions.first()) {
_ep.remove(_rom_sessions.first());
_close(_rom_sessions.first());
}
while (_rom_sessions.first())
_close(*_rom_sessions.first());
}
Genode::Session_capability session(char const *args,
Affinity const &affinity)
Rom_session_component &create(Args const &args, Affinity affinity) override
{
/* try to find ROM module at local ROM service */
try {
Lock::Guard guard(_lock);
Session_label const label = label_from_args(args);
Session_label name = label.last_element();
Session_label const label = label_from_args(args.string());
Session_label const name = label.last_element();
Rom_module &module = _rom_modules.lookup_and_lock(name.string());
Rom_session_component *rom = new (&_md_alloc)
Rom_session_component(module);
Rom_session_component *rom = new (_md_alloc)
Rom_session_component(_ep, module);
_rom_sessions.insert(rom);
return _ep.manage(rom);
return *rom;
} catch (...) { }
/* fall back to parent_rom_service */
return _parent_rom_service.session(args, affinity);
throw Denied();
}
void close(Session_capability session)
void upgrade(Rom_session_component &, Args const &) override { }
void destroy(Rom_session_component &session) override
{
Lock::Guard guard(_lock);
Rom_session_component *component;
_ep.apply(session, [&] (Rom_session_component *rsc) {
component = rsc;
if (component) _ep.remove(component);
});
if (component) {
_close(component);
return;
}
_parent_rom_service.close(session);
_close(session);
}
void upgrade(Session_capability session, const char *) { }
};
typedef Local_service<Rom_session_component> Local_rom_service;
/**
* Common base class of 'Local_cpu_service' and 'Local_pd_service'
*/
struct Intercepted_parent_service : Service
struct Intercepted_parent_service : Genode::Parent_service
{
Signal_context_capability fault_sigh;
Intercepted_parent_service(char const *name) : Service(name) { }
void close(Session_capability session)
{
env()->parent()->close(session);
}
void upgrade(Session_capability session, const char *) { }
Intercepted_parent_service(Env &env, Service::Name const &name)
: Parent_service(env, name) { }
};
/**
@ -147,20 +121,17 @@ class Loader::Session_component : public Rpc_object<Session>
*/
struct Local_cpu_service : Intercepted_parent_service
{
Local_cpu_service() : Intercepted_parent_service("CPU") { }
Local_cpu_service(Env &env) : Intercepted_parent_service(env, "CPU") { }
Genode::Session_capability session(char const *args,
Affinity const &affinity)
void initiate_request(Session_state &session) override
{
Capability<Cpu_session> cap = env()->parent()->session<Cpu_session>(args, affinity);
Cpu_session_client(cap).exception_sigh(fault_sigh);
return cap;
}
Intercepted_parent_service::initiate_request(session);
void upgrade(Session_capability session, const char *args)
{
try { env()->parent()->upgrade(session, args); }
catch (Genode::Ipc_error) { throw Unavailable(); }
if (session.phase != Session_state::AVAILABLE)
return;
Cpu_session_client cpu(reinterpret_cap_cast<Cpu_session>(session.cap));
cpu.exception_sigh(fault_sigh);
}
};
@ -169,109 +140,100 @@ class Loader::Session_component : public Rpc_object<Session>
*/
struct Local_pd_service : Intercepted_parent_service
{
Local_pd_service() : Intercepted_parent_service("PD") { }
Local_pd_service(Env &env) : Intercepted_parent_service(env, "PD") { }
Genode::Session_capability session(char const *args,
Affinity const &affinity)
void initiate_request(Session_state &session) override
{
Pd_session_client pd(env()->parent()->session<Pd_session>(args, affinity));
Intercepted_parent_service::initiate_request(session);
if (session.phase != Session_state::AVAILABLE)
return;
Pd_session_client pd(reinterpret_cap_cast<Pd_session>(session.cap));
Region_map_client(pd.address_space()).fault_handler(fault_sigh);
Region_map_client(pd.stack_area()) .fault_handler(fault_sigh);
Region_map_client(pd.linker_area()) .fault_handler(fault_sigh);
return pd;
}
};
struct Local_nitpicker_service : Service
struct Local_nitpicker_factory : Local_service<Nitpicker::Session_component>::Factory
{
Rpc_entrypoint &_ep;
Ram_session &_ram;
Allocator &_md_alloc;
Entrypoint &_ep;
Ram_session &_ram;
Area _max_size;
Nitpicker::View_capability _parent_view;
Signal_context_capability view_ready_sigh;
Nitpicker::Session_component *open_session;
Lazy_volatile_object<Nitpicker::Session_component> session;
Local_nitpicker_service(Rpc_entrypoint &ep, Ram_session &ram,
Allocator &md_alloc)
:
Service("virtual_nitpicker"),
_ep(ep),
_ram(ram),
_md_alloc(md_alloc),
open_session(0)
{ }
Local_nitpicker_factory(Entrypoint &ep, Ram_session &ram)
: _ep(ep), _ram(ram) { }
~Local_nitpicker_service()
{
if (!open_session)
return;
_ep.dissolve(open_session);
destroy(&_md_alloc, open_session);
}
void constrain_geometry(Area size)
{
_max_size = size;
}
void constrain_geometry(Area size) { _max_size = size; }
void parent_view(Nitpicker::View_capability view)
{
_parent_view = view;
}
Genode::Session_capability session(char const *args,
Affinity const &)
Nitpicker::Session_component &create(Args const &args, Affinity) override
{
if (open_session)
throw Unavailable();
if (session.constructed()) {
warning("attempt to open more than one nitpicker session");
throw Parent::Service_denied();
}
open_session = new (&_md_alloc)
Nitpicker::Session_component(_ep,
_ram,
_max_size,
_parent_view,
view_ready_sigh,
args);
return _ep.manage(open_session);
session.construct(_ep, _ram, _max_size,
_parent_view, view_ready_sigh, args.string());
return *session;
}
void upgrade(Genode::Session_capability session, const char *) { }
void upgrade(Nitpicker::Session_component &, Args const &) override { }
void destroy(Nitpicker::Session_component &) override { }
};
typedef Local_service<Nitpicker::Session_component> Local_nitpicker_service;
enum { STACK_SIZE = 2*4096 };
size_t _ram_quota;
Ram_session_client_guard _ram_session_client;
Heap _md_alloc;
size_t _subsystem_ram_quota_limit;
Rpc_entrypoint _ep;
Dataspace_capability _ldso_ds;
Service_registry _parent_services;
Rom_module_registry _rom_modules;
Local_rom_service _rom_service;
Local_cpu_service _cpu_service;
Local_pd_service _pd_service;
Local_nitpicker_service _nitpicker_service;
Signal_context_capability _fault_sigh;
Child *_child;
Env &_env;
Session_label const _label;
Xml_node const _config;
size_t const _ram_quota;
Ram_session_client_guard _local_ram { _env.ram_session_cap(), _ram_quota };
Heap _md_alloc { _local_ram, _env.rm() };
size_t _subsystem_ram_quota_limit = 0;
Parent_services _parent_services;
Rom_module_registry _rom_modules { _env, _config, _local_ram, _md_alloc };
Local_rom_factory _rom_factory { _env.ep(), _md_alloc, _rom_modules };
Local_rom_service _rom_service { _rom_factory };
Local_cpu_service _cpu_service { _env };
Local_pd_service _pd_service { _env };
Local_nitpicker_factory _nitpicker_factory { _env.ep(), _local_ram };
Local_nitpicker_service _nitpicker_service { _nitpicker_factory };
Signal_context_capability _fault_sigh;
Lazy_volatile_object<Child> _child;
/**
* Return virtual nitpicker session component
*/
Nitpicker::Session_component &_virtual_nitpicker_session() const
Nitpicker::Session_component &_virtual_nitpicker_session()
{
if (!_nitpicker_service.open_session)
if (!_nitpicker_factory.session.constructed())
throw View_does_not_exist();
return *_nitpicker_service.open_session;
return *_nitpicker_factory.session;
}
Nitpicker::Session_component const &_virtual_nitpicker_session() const
{
if (!_nitpicker_factory.session.constructed())
throw View_does_not_exist();
return *_nitpicker_factory.session;
}
public:
@ -279,34 +241,30 @@ class Loader::Session_component : public Rpc_object<Session>
/**
* Constructor
*/
Session_component(size_t quota, Ram_session &ram, Cap_session &cap,
Dataspace_capability ldso_ds)
Session_component(Env &env, Session_label const &label,
Xml_node config, size_t quota)
:
_ram_quota(quota),
_ram_session_client(env()->ram_session_cap(), _ram_quota),
_md_alloc(&_ram_session_client, env()->rm_session()),
_subsystem_ram_quota_limit(0),
_ep(&cap, STACK_SIZE, "session_ep"),
_ldso_ds(ldso_ds),
_rom_modules(_ram_session_client, _md_alloc),
_rom_service(_ep, _md_alloc, _rom_modules),
_nitpicker_service(_ep, _ram_session_client, _md_alloc),
_child(0)
{ }
_env(env), _label(label), _config(config), _ram_quota(quota)
{
/* fetch all parent-provided ROMs according to the config */
config.for_each_sub_node("parent-rom", [&] (Xml_node rom)
{
typedef Rom_module::Name Name;
Name name = rom.attribute_value("name", Name());
_rom_modules.fetch_parent_rom_module(name);
});
}
~Session_component()
{
if (_child)
destroy(&_md_alloc, _child);
_child.destruct();
/*
* The parent-service registry is populated by the 'Child'
* on demand. Revert those allocations.
*/
while (Service *service = _parent_services.find_by_server(0)) {
_parent_services.remove(service);
destroy(env()->heap(), service);
}
_parent_services.for_each([&] (Parent_service &service) {
destroy(env()->heap(), &service); });
}
@ -334,17 +292,17 @@ class Loader::Session_component : public Rpc_object<Session>
void constrain_geometry(Area size) override
{
_nitpicker_service.constrain_geometry(size);
_nitpicker_factory.constrain_geometry(size);
}
void parent_view(Nitpicker::View_capability view) override
{
_nitpicker_service.parent_view(view);
_nitpicker_factory.parent_view(view);
}
void view_ready_sigh(Signal_context_capability sigh) override
{
_nitpicker_service.view_ready_sigh = sigh;
_nitpicker_factory.view_ready_sigh = sigh;
}
void fault_sigh(Signal_context_capability sigh) override
@ -369,22 +327,21 @@ class Loader::Session_component : public Rpc_object<Session>
void start(Name const &binary_name, Name const &label) override
{
if (_child) {
PWRN("cannot start subsystem twice");
if (_child.constructed()) {
warning("cannot start subsystem twice");
return;
}
size_t const ram_quota = (_subsystem_ram_quota_limit > 0) ?
min(_subsystem_ram_quota_limit, _ram_session_client.avail()) :
_ram_session_client.avail();
size_t const ram_quota = (_subsystem_ram_quota_limit > 0)
? min(_subsystem_ram_quota_limit, _ram_quota)
: _ram_quota;
try {
_child = new (&_md_alloc)
Child(binary_name.string(), label.string(), _ldso_ds,
_ep, _ram_session_client,
ram_quota, _parent_services, _rom_service,
_cpu_service, _pd_service, _nitpicker_service,
_fault_sigh);
_child.construct(_env, binary_name.string(),
prefixed_label(_label, Session_label(label.string())),
ram_quota, _parent_services, _rom_service,
_cpu_service, _pd_service, _nitpicker_service,
_fault_sigh);
}
catch (Genode::Parent::Service_denied) {
throw Rom_module_does_not_exist(); }
@ -406,61 +363,53 @@ class Loader::Root : public Root_component<Session_component>
{
private:
Ram_session &_ram;
Cap_session &_cap;
Dataspace_capability _ldso_ds;
Env &_env;
Xml_node const _config;
protected:
Session_component *_create_session(const char *args)
{
size_t quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
size_t quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
return new (md_alloc()) Session_component(quota, _ram, _cap, _ldso_ds);
Xml_node session_config("<policy/>");
Session_label const label = label_from_args(args);
try { session_config = Session_policy(label, _config); }
catch (...) { }
return new (md_alloc()) Session_component(_env, label, session_config, quota);
}
public:
/**
* Constructor
*
* \param session_ep entry point for managing ram session objects
* \param md_alloc meta-data allocator to be used by root
* component
*/
Root(Rpc_entrypoint &session_ep, Allocator &md_alloc,
Ram_session &ram, Cap_session &cap, Dataspace_capability ldso_ds)
Root(Env &env, Xml_node config, Allocator &md_alloc)
:
Root_component<Session_component>(&session_ep, &md_alloc),
_ram(ram), _cap(cap), _ldso_ds(ldso_ds)
Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
_env(env), _config(config)
{ }
};
Genode::Dataspace_capability request_ldso_ds()
namespace Loader { struct Main; }
struct Loader::Main
{
try {
static Genode::Rom_connection rom("ld.lib.so");
return rom.dataspace();
} catch (...) { }
return Genode::Dataspace_capability();
}
Env &env;
Heap heap { env.ram(), env.rm() };
Attached_rom_dataspace config { env, "config" };
Root root { env, config.xml(), heap };
Main(Env &env) : env(env)
{
env.parent().announce(env.ep().manage(root));
}
};
int main()
{
using namespace Genode;
enum { STACK_SIZE = 8*1024 };
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "loader_ep");
static Loader::Root root(ep, *env()->heap(), *env()->ram_session(), cap,
request_ldso_ds());
env()->parent()->announce(ep.manage(&root));
sleep_forever();
return 0;
}
void Component::construct(Genode::Env &env) { static Loader::Main main(env); }

View File

@ -39,7 +39,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>
*/
Genode::Signal_context_capability _view_ready_sigh;
Genode::Rpc_entrypoint &_ep;
Genode::Entrypoint &_ep;
Area _max_size;
@ -148,7 +148,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>
/**
* Constructor
*/
Session_component(Genode::Rpc_entrypoint &ep,
Session_component(Genode::Entrypoint &ep,
Genode::Ram_session &ram,
Area max_size,
Nitpicker::View_capability parent_view,
@ -166,10 +166,18 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>
_view_handle(_nitpicker.create_view(_parent_view_handle)),
_proxy_input(_nitpicker.input_session(), _motion_delta),
_proxy_input_cap(_ep.manage(&_proxy_input)),
_proxy_input_cap(_ep.manage(_proxy_input)),
_command_ds(&ram, sizeof(Command_buffer))
{ }
{
_ep.manage(*this);
}
~Session_component()
{
_ep.dissolve(_proxy_input);
_ep.dissolve(*this);
}
/*********************************

View File

@ -11,20 +11,26 @@
#include <rom_session/rom_session.h>
#include <base/rpc_server.h>
#include <os/attached_ram_dataspace.h>
#include <os/attached_rom_dataspace.h>
namespace Genode {
class Rom_module : public List<Rom_module>::Element
{
public:
typedef String<128> Name;
private:
enum { MAX_NAME_LEN = 64 };
char _name[MAX_NAME_LEN];
Name const _name;
Ram_session &_ram;
Attached_ram_dataspace _fg;
Attached_ram_dataspace _bg;
Lazy_volatile_object<Attached_rom_dataspace> _parent_rom;
bool _bg_has_pending_data;
Signal_context_capability _sigh;
@ -33,20 +39,28 @@ namespace Genode {
public:
Rom_module(char const *name, Ram_session &ram_session)
enum Origin { PARENT_PROVIDED, SESSION_LOCAL };
Rom_module(Env &env, Xml_node config, Name const &name,
Ram_session &ram_session, Origin origin)
:
_ram(ram_session),
_name(name), _ram(ram_session),
_fg(&_ram, 0), _bg(&_ram, 0),
_bg_has_pending_data(false),
_lock(Lock::LOCKED)
{
strncpy(_name, name, sizeof(_name));
if (origin == SESSION_LOCAL)
return;
try {
_parent_rom.construct(env, name.string()); }
catch (...) {
warning("ROM ", name, " unavailable from parent, "
"try to use session-local ROM");
}
}
bool has_name(char const *name) const
{
return strcmp(_name, name) == 0;
}
bool has_name(Name const &name) const { return _name == name; }
void lock() { _lock.lock(); }
void unlock() { _lock.unlock(); }
@ -72,6 +86,9 @@ namespace Genode {
*/
Rom_dataspace_capability fg_dataspace()
{
if (_parent_rom.constructed())
return static_cap_cast<Rom_dataspace>(_parent_rom->cap());
if (!_fg.size() && !_bg_has_pending_data) {
Genode::error("no data loaded");
return Rom_dataspace_capability();
@ -95,7 +112,13 @@ namespace Genode {
*
* This function is indirectly called by the ROM session client.
*/
void sigh(Signal_context_capability sigh) { _sigh = sigh; }
void sigh(Signal_context_capability sigh)
{
if (_parent_rom.constructed())
_parent_rom->sigh(sigh);
_sigh = sigh;
}
/**
* Commit data contained in background dataspace
@ -126,6 +149,8 @@ namespace Genode {
{
private:
Env &_env;
Xml_node const _config;
Lock _lock;
Ram_session &_ram_session;
Allocator &_md_alloc;
@ -145,9 +170,11 @@ namespace Genode {
* module data
* \param md_alloc backing store for ROM module meta data
*/
Rom_module_registry(Ram_session &ram_session, Allocator &md_alloc)
Rom_module_registry(Env &env, Xml_node config, Ram_session &ram_session,
Allocator &md_alloc)
:
_ram_session(ram_session), _md_alloc(md_alloc)
_env(env), _config(config), _ram_session(ram_session),
_md_alloc(md_alloc)
{ }
~Rom_module_registry()
@ -167,7 +194,7 @@ namespace Genode {
*
* \throw Lookup_failed
*/
Rom_module &lookup_and_lock(char const *name)
Rom_module &lookup_and_lock(Rom_module::Name const &name)
{
Lock::Guard guard(_lock);
@ -181,7 +208,7 @@ namespace Genode {
throw Lookup_failed();
}
Dataspace_capability alloc_rom_module(char const *name, size_t size)
Dataspace_capability alloc_rom_module(Rom_module::Name const &name, size_t size)
{
try {
Rom_module &module = lookup_and_lock(name);
@ -193,7 +220,8 @@ namespace Genode {
Lock::Guard guard(_lock);
Rom_module *module = new (&_md_alloc)
Rom_module(name, _ram_session);
Rom_module(_env, _config, name, _ram_session,
Rom_module::SESSION_LOCAL);
Rom_module_lock_guard module_guard(*module);
@ -203,6 +231,25 @@ namespace Genode {
}
}
void fetch_parent_rom_module(Rom_module::Name const &name)
{
try {
lookup_and_lock(name);
}
catch (Lookup_failed) {
Lock::Guard guard(_lock);
Rom_module *module = new (&_md_alloc)
Rom_module(_env, _config, name, _ram_session,
Rom_module::PARENT_PROVIDED);
Rom_module_lock_guard module_guard(*module);
_list.insert(module);
}
}
/**
* \throw Lookup_failed
*/
@ -220,12 +267,15 @@ namespace Genode {
{
private:
Entrypoint &_ep;
Rom_module &_rom_module;
public:
Rom_session_component(Rom_module &rom_module)
: _rom_module(rom_module) { }
Rom_session_component(Entrypoint &ep, Rom_module &rom_module)
: _ep(ep), _rom_module(rom_module) { _ep.manage(*this); }
~Rom_session_component() { _ep.dissolve(*this); }
Rom_dataspace_capability dataspace()
{

View File

@ -691,7 +691,7 @@ class Audio_out::Root : public Audio_out::Root_component
void _destroy_session(Session_component *session)
{
if (--_sessions == 0) _mixer.stop();
destroy(md_alloc(), session);
Genode::destroy(md_alloc(), session);
}
public:

View File

@ -1072,7 +1072,7 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
session->destroy_all_views();
_mode.forget(*session);
destroy(md_alloc(), session);
Genode::destroy(md_alloc(), session);
}
public: