mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 14:37:50 +00:00
base: handle dangling env sessions in ~Child
This commit addresses the situation where an environment session outlives the session-providing service. In this case, the env session got already invaidated at the destruction time of the server. However, the underlying session-state structure continues to exist until the client is destructed. During the eventual destruction of such a dangling environment session, we have to be careful not to interact with the no-longer existing service. Ref #2197
This commit is contained in:
parent
21458e6efa
commit
e43da51bd6
@ -467,6 +467,8 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
void _revert_quota_and_destroy(Session_state &);
|
||||
|
||||
void _discard_env_session(Id_space<Parent::Client>::Id);
|
||||
|
||||
Close_result _close(Session_state &);
|
||||
|
||||
/**
|
||||
|
@ -620,9 +620,18 @@ void Child::_try_construct_env_dependent_members()
|
||||
}
|
||||
|
||||
|
||||
Child::Child(Region_map &local_rm,
|
||||
Rpc_entrypoint &entrypoint,
|
||||
Child_policy &policy)
|
||||
void Child::_discard_env_session(Id_space<Parent::Client>::Id id)
|
||||
{
|
||||
auto discard_id_fn = [&] (Session_state &s) { s.discard_id_at_client(); };
|
||||
|
||||
try { _id_space.apply<Session_state>(id, discard_id_fn); }
|
||||
catch (Id_space<Parent::Client>::Unknown_id) { }
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
@ -668,12 +677,10 @@ Child::~Child()
|
||||
/*
|
||||
* Remove statically created env sessions from the child's ID space.
|
||||
*/
|
||||
auto discard_id_fn = [&] (Session_state &s) { s.discard_id_at_client(); };
|
||||
|
||||
_id_space.apply<Session_state>(Env::ram(), discard_id_fn);
|
||||
_id_space.apply<Session_state>(Env::cpu(), discard_id_fn);
|
||||
_id_space.apply<Session_state>(Env::pd(), discard_id_fn);
|
||||
_id_space.apply<Session_state>(Env::log(), discard_id_fn);
|
||||
_discard_env_session(Env::ram());
|
||||
_discard_env_session(Env::cpu());
|
||||
_discard_env_session(Env::pd());
|
||||
_discard_env_session(Env::log());
|
||||
|
||||
/*
|
||||
* Remove dynamically created sessions from the child's ID space.
|
||||
|
@ -94,6 +94,14 @@ void Session_state::destroy()
|
||||
*/
|
||||
id_at_server.destruct();
|
||||
|
||||
/*
|
||||
* Make sure that the session does not appear as being alive. I.e., if
|
||||
* 'destroy' was called during the destruction of a service, prevent the
|
||||
* 'Local_connection' destructor of a dangling session to initiate a close
|
||||
* request to the no-longer existing service.
|
||||
*/
|
||||
phase = CLOSED;
|
||||
|
||||
if (_factory)
|
||||
_factory->_destroy(*this);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user