mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-19 11:16:57 +00:00
base: consider exception during child construction
This patch make sure that a once managed parent RPC object will always be dissolved if an exception during the remaining child construction occurs. The original version would miss the dissolve call if one of the subsequent members throws an exception at construction time.
This commit is contained in:
parent
4d3d4ecca0
commit
2c6729768d
@ -317,8 +317,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
Region_map &_local_rm;
|
||||
|
||||
Rpc_entrypoint &_entrypoint;
|
||||
Parent_capability _parent_cap;
|
||||
Capability_guard _parent_cap_guard;
|
||||
|
||||
/* signal handlers registered by the child */
|
||||
Signal_context_capability _resource_avail_sigh;
|
||||
|
@ -265,9 +265,7 @@ class Genode::Rpc_object_base : public Object_pool<Rpc_object_base>::Entry
|
||||
template <typename RPC_INTERFACE, typename SERVER = RPC_INTERFACE>
|
||||
struct Genode::Rpc_object : Rpc_object_base, Rpc_dispatcher<RPC_INTERFACE, SERVER>
|
||||
{
|
||||
/*****************************
|
||||
** Server-object interface **
|
||||
*****************************/
|
||||
struct Capability_guard;
|
||||
|
||||
Rpc_exception_code dispatch(Rpc_opcode opcode, Ipc_unmarshaller &in, Msgbuf_base &out)
|
||||
{
|
||||
@ -503,4 +501,17 @@ class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
|
||||
void cancel_blocking() { Thread::cancel_blocking(); }
|
||||
};
|
||||
|
||||
|
||||
template <typename IF, typename SERVER>
|
||||
struct Genode::Rpc_object<IF, SERVER>::Capability_guard
|
||||
{
|
||||
Rpc_entrypoint &_ep;
|
||||
Rpc_object &_obj;
|
||||
|
||||
Capability_guard(Rpc_entrypoint &ep, Rpc_object &obj)
|
||||
: _ep(ep), _obj(obj) { _ep.manage(&_obj); }
|
||||
|
||||
~Capability_guard() { _ep.dissolve(&_obj); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__RPC_SERVER_H_ */
|
||||
|
@ -707,7 +707,7 @@ void Child::_try_construct_env_dependent_members()
|
||||
_pd.cap(), _pd.session(), _ram.session(),
|
||||
*_initial_thread, _local_rm,
|
||||
Child_address_space(_pd.session(), _policy).region_map(),
|
||||
_parent_cap);
|
||||
cap());
|
||||
}
|
||||
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
|
||||
catch (Out_of_caps) { _error("out of caps during ELF loading"); }
|
||||
@ -757,8 +757,7 @@ Child::Child(Region_map &local_rm,
|
||||
Rpc_entrypoint &entrypoint,
|
||||
Child_policy &policy)
|
||||
:
|
||||
_policy(policy), _local_rm(local_rm), _entrypoint(entrypoint),
|
||||
_parent_cap(_entrypoint.manage(this))
|
||||
_policy(policy), _local_rm(local_rm), _parent_cap_guard(entrypoint, *this)
|
||||
{
|
||||
if (_policy.initiate_env_sessions()) {
|
||||
initiate_env_ram_session();
|
||||
@ -769,8 +768,6 @@ Child::Child(Region_map &local_rm,
|
||||
|
||||
Child::~Child()
|
||||
{
|
||||
_entrypoint.dissolve(this);
|
||||
|
||||
/*
|
||||
* Purge the meta data about any dangling sessions provided by the child to
|
||||
* other children.
|
||||
|
Loading…
Reference in New Issue
Block a user