genode/repos/ports/src/noux/rom_session_component.h
Norman Feske b44f0554bd Adapt high-level components to new parent API
This patch adjusts the various users of the 'Child' API to the changes
on the account of the new non-blocking parent interface. It also removes
the use of the no-longer-available 'Connection::KEEP_OPEN' feature.

With the adjustment, we took the opportunity to redesign several
components to fit the non-blocking execution model much better, in
particular the demo applications.

Issue #2120
2016-11-30 13:37:03 +01:00

167 lines
3.9 KiB
C++

/*
* \brief ROM session implementation used by Noux processes
* \author Norman Feske
* \date 2013-07-18
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _NOUX__ROM_SESSION_COMPONENT_H_
#define _NOUX__ROM_SESSION_COMPONENT_H_
/* Genode includes */
#include <rom_session/connection.h>
#include <base/rpc_server.h>
namespace Noux {
struct Rom_dataspace_info;
class Rom_session_component;
}
struct Noux::Rom_dataspace_info : Dataspace_info
{
Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { }
~Rom_dataspace_info() { }
Dataspace_capability fork(Ram_session &,
Dataspace_registry &ds_registry,
Rpc_entrypoint &) override
{
ds_registry.insert(new (env()->heap()) Rom_dataspace_info(ds_cap()));
return ds_cap();
}
void poke(addr_t dst_offset, void const *src, size_t len)
{
error("attempt to poke onto a ROM dataspace");
}
};
/**
* Local ROM service
*
* Depending on the ROM name, the data is provided by the VFS (if the name
* starts with a '/' or the parent's ROM service. If the name empty, an
* invalid dataspace capability is returned (this is used for the binary
* ROM session of a forked process).
*/
class Noux::Rom_session_component : public Rpc_object<Rom_session>
{
public:
typedef Child_policy::Name Name;
/**
* Label of ROM session requested for the binary of a forked process
*
* In this case, the loading of the binary must be omitted because the
* address space is replayed by the fork operation. Hence, requests for
* such ROM modules are answered by an invalid dataspace, which is
* handled in 'Child::Process'.
*/
static Name forked_magic_binary_name() { return "(forked)"; }
private:
Rpc_entrypoint &_ep;
Vfs::Dir_file_system &_root_dir;
Dataspace_registry &_ds_registry;
/**
* Dataspace obtained from the VFS
*/
struct Vfs_dataspace
{
Vfs::Dir_file_system &root_dir;
Name const name;
Dataspace_capability const ds;
Vfs_dataspace(Vfs::Dir_file_system &root_dir, Name const &name)
:
root_dir(root_dir), name(name), ds(root_dir.dataspace(name.string()))
{ }
~Vfs_dataspace() { root_dir.release(name.string(), ds); }
};
Lazy_volatile_object<Vfs_dataspace> _rom_from_vfs;
/**
* Wrapped ROM session at core
*/
Lazy_volatile_object<Rom_connection> _rom_from_parent;
Dataspace_capability _init_ds_cap(Name const &name)
{
if (name.string()[0] == '/') {
_rom_from_vfs.construct(_root_dir, name);
return _rom_from_vfs->ds;
}
if (name == forked_magic_binary_name())
return Dataspace_capability();
_rom_from_parent.construct(name.string());
Dataspace_capability ds = _rom_from_parent->dataspace();
return ds;
}
Dataspace_capability const _ds_cap;
public:
Rom_session_component(Rpc_entrypoint &ep, Vfs::Dir_file_system &root_dir,
Dataspace_registry &ds_registry, Name const &name)
:
_ep(ep), _root_dir(root_dir), _ds_registry(ds_registry),
_ds_cap(_init_ds_cap(name))
{
_ep.manage(this);
_ds_registry.insert(new (env()->heap()) Rom_dataspace_info(_ds_cap));
}
~Rom_session_component()
{
/*
* Lookup and lock ds info instead of directly accessing
* the '_ds_info' member.
*/
_ds_registry.apply(_ds_cap, [this] (Dataspace_info *info) {
if (!info) {
error("~Rom_session_component: unexpected !info");
return;
}
_ds_registry.remove(info);
info->dissolve_users();
});
_ep.dissolve(this);
}
/***************************
** ROM session interface **
***************************/
Rom_dataspace_capability dataspace()
{
return static_cap_cast<Rom_dataspace>(_ds_cap);
}
void sigh(Signal_context_capability) { }
};
#endif /* _NOUX__ROM_SESSION_COMPONENT_H_ */