base: close PD on 'close_all_sessions'

This patch moves the closing of a child's PD session from the 'Child'
destructor to the 'close_all_sessions' method. This way, the child's
PD quota is immediately returned as soon as init flags a child as
'abandoned', which removes jitter from init's RAM-state reports.

The patch is supposed to make the 'init_loop.run' test much happier.
This commit is contained in:
Norman Feske 2018-06-25 14:55:59 +02:00
parent 1b993714c5
commit ddff89d43e

View File

@ -125,9 +125,12 @@ create_session(Child_policy::Name const &child_name, Service &service,
error(child_name, " requested conflicting session ID ", id, " " error(child_name, " requested conflicting session ID ", id, " "
"(service=", service.name(), " args=", args, ")"); "(service=", service.name(), " args=", args, ")");
try {
id_space.apply<Session_state>(id, [&] (Session_state &session) { id_space.apply<Session_state>(id, [&] (Session_state &session) {
error("existing session: ", session); }); error("existing session: ", session); });
} }
catch (Id_space<Parent::Client>::Unknown_id) { }
}
throw Service_denied(); throw Service_denied();
} }
@ -165,7 +168,7 @@ Session_capability Child::session(Parent::Client::Id id,
Parent::Session_args const &args, Parent::Session_args const &args,
Affinity const &affinity) Affinity const &affinity)
{ {
if (!name.valid_string() || !args.valid_string()) if (!name.valid_string() || !args.valid_string() || _pd.closed())
throw Service_denied(); throw Service_denied();
char argbuf[Parent::Session_args::MAX_SIZE]; char argbuf[Parent::Session_args::MAX_SIZE];
@ -338,9 +341,13 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
return UPGRADE_DONE; return UPGRADE_DONE;
} }
/* ignore suprious request that may arrive after 'close_all_sessions' */
if (_pd.closed())
return UPGRADE_PENDING;
Upgrade_result result = UPGRADE_PENDING; Upgrade_result result = UPGRADE_PENDING;
_id_space.apply<Session_state>(id, [&] (Session_state &session) { auto upgrade_session = [&] (Session_state &session) {
if (session.phase != Session_state::CAP_HANDED_OUT) { if (session.phase != Session_state::CAP_HANDED_OUT) {
warning("attempt to upgrade session in invalid state"); warning("attempt to upgrade session in invalid state");
@ -395,7 +402,11 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
} }
session.service().wakeup(); session.service().wakeup();
}); };
try { _id_space.apply<Session_state>(id, upgrade_session); }
catch (Id_space<Parent::Client>::Unknown_id) { }
_policy.session_state_changed(); _policy.session_state_changed();
return result; return result;
} }
@ -612,7 +623,10 @@ void Child::session_response(Server::Id id, Session_response response)
break; break;
} }
}); });
} catch (Child_policy::Nonexistent_id_space) { } }
catch (Child_policy::Nonexistent_id_space) { }
catch (Id_space<Parent::Client>::Unknown_id) {
warning("unexpected session response for unknown session"); }
} }
@ -621,6 +635,10 @@ void Child::deliver_session_cap(Server::Id id, Session_capability cap)
try { try {
_policy.server_id_space().apply<Session_state>(id, [&] (Session_state &session) { _policy.server_id_space().apply<Session_state>(id, [&] (Session_state &session) {
/* ignore responses after 'close_all_sessions' of the client */
if (session.phase != Session_state::CREATE_REQUESTED)
return;
if (session.cap.valid()) { if (session.cap.valid()) {
_error("attempt to assign session cap twice"); _error("attempt to assign session cap twice");
return; return;
@ -632,7 +650,9 @@ void Child::deliver_session_cap(Server::Id id, Session_capability cap)
if (session.ready_callback) if (session.ready_callback)
session.ready_callback->session_ready(session); session.ready_callback->session_ready(session);
}); });
} catch (Child_policy::Nonexistent_id_space) { } }
catch (Child_policy::Nonexistent_id_space) { }
catch (Id_space<Parent::Client>::Unknown_id) { }
} }
@ -854,13 +874,13 @@ void Child::close_all_sessions()
/* /*
* Issue close requests to the providers of the environment sessions, * Issue close requests to the providers of the environment sessions,
* which may be async services. Don't close the PD session since it * which may be async services.
* is still needed for reverting session quotas.
*/ */
_log.close(); _log.close();
_binary.close(); _binary.close();
if (_linker.constructed()) if (_linker.constructed())
_linker->close(); _linker->close();
_pd.close();
/* /*
* Remove statically created env sessions from the child's ID space. * Remove statically created env sessions from the child's ID space.