mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-02 20:16:48 +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 _revert_quota_and_destroy(Session_state &);
|
||||||
|
|
||||||
|
void _discard_env_session(Id_space<Parent::Client>::Id);
|
||||||
|
|
||||||
Close_result _close(Session_state &);
|
Close_result _close(Session_state &);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -620,6 +620,15 @@ void Child::_try_construct_env_dependent_members()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
Child::Child(Region_map &local_rm,
|
||||||
Rpc_entrypoint &entrypoint,
|
Rpc_entrypoint &entrypoint,
|
||||||
Child_policy &policy)
|
Child_policy &policy)
|
||||||
@ -668,12 +677,10 @@ Child::~Child()
|
|||||||
/*
|
/*
|
||||||
* Remove statically created env sessions from the child's ID space.
|
* Remove statically created env sessions from the child's ID space.
|
||||||
*/
|
*/
|
||||||
auto discard_id_fn = [&] (Session_state &s) { s.discard_id_at_client(); };
|
_discard_env_session(Env::ram());
|
||||||
|
_discard_env_session(Env::cpu());
|
||||||
_id_space.apply<Session_state>(Env::ram(), discard_id_fn);
|
_discard_env_session(Env::pd());
|
||||||
_id_space.apply<Session_state>(Env::cpu(), discard_id_fn);
|
_discard_env_session(Env::log());
|
||||||
_id_space.apply<Session_state>(Env::pd(), discard_id_fn);
|
|
||||||
_id_space.apply<Session_state>(Env::log(), discard_id_fn);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove dynamically created sessions from the child's ID space.
|
* Remove dynamically created sessions from the child's ID space.
|
||||||
|
@ -94,6 +94,14 @@ void Session_state::destroy()
|
|||||||
*/
|
*/
|
||||||
id_at_server.destruct();
|
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)
|
if (_factory)
|
||||||
_factory->_destroy(*this);
|
_factory->_destroy(*this);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user