base: handle cancelation of session creation

This patch improves the handling of the corner case where a client
vanishes while a session request is in flight (CREATE_REQUESTED but
not yet AVAILABLE). This corner case could be sporadically observed with
the init_loop test on base-linux.

In the original version, the session would eventually be delivered but
never picked up by anyone. Such a stale session still uses resources that
should better be released. In the new version, the parent checks for the
liveliness of the client whenever a session is delivered. If there is no
client of the session, a close request is immediately issued to the
server. The session state must be preserved until the close requests has
been answered.
This commit is contained in:
Norman Feske 2018-06-26 12:05:31 +02:00
parent ddff89d43e
commit a3858bff3c
2 changed files with 16 additions and 0 deletions

View File

@ -236,6 +236,8 @@ class Genode::Session_state : public Parent::Client, public Parent::Server
*/
Session::Label client_label() const { return label_from_args(_args.string()); }
bool client_exists() const { return _id_at_client.constructed(); }
/**
* Return label presented to the server along with the session request
*/

View File

@ -644,6 +644,20 @@ void Child::deliver_session_cap(Server::Id id, Session_capability cap)
return;
}
/*
* If the client vanished during the session creation, the
* session-close state change must be reflected to the server
* as soon as the session becomes available. This enables the
* server to wind down the session. If we just discarded the
* session, the server's ID space would become inconsistent
* with ours.
*/
if (!session.client_exists()) {
session.phase = Session_state::CLOSE_REQUESTED;
session.service().initiate_request(session);
return;
}
session.cap = cap;
session.phase = Session_state::AVAILABLE;