diff --git a/repos/os/src/init/server.cc b/repos/os/src/init/server.cc index 7a321a326f..5a112e4375 100644 --- a/repos/os/src/init/server.cc +++ b/repos/os/src/init/server.cc @@ -109,7 +109,7 @@ Init::Server::_resolve_session_request(Service::Name const &service_name, matching_service = &service; }); if (!matching_service) - throw Service_denied(); + throw Service_not_present(); return matching_service->resolve_session_request(label); } @@ -169,6 +169,16 @@ void Init::Server::session_closed(Session_state &session) void Init::Server::_handle_create_session_request(Xml_node request, Parent::Client::Id id) { + /* + * Ignore requests that are already successfully forwarded (by a prior call + * of '_handle_create_session_request') but still remain present in the + * 'session_requests' ROM because the server child has not responded yet. + */ + try { + _client_id_space.apply(id, [&] (Parent::Client const &) { }); + return; + } catch (Id_space::Unknown_id) { /* normal case */ } + if (!request.has_sub_node("args")) return; @@ -257,6 +267,7 @@ void Init::Server::_handle_create_session_request(Xml_node request, catch (Insufficient_cap_quota) { _env.parent().session_response(Parent::Server::Id { id.value }, Parent::INSUFFICIENT_CAP_QUOTA); } + catch (Service_not_present) { /* keep request pending */ } } @@ -356,11 +367,15 @@ void Init::Server::apply_config(Xml_node config) _session_request_handler.construct(_env.ep(), *this, &Server::_handle_session_requests); _session_requests->sigh(*_session_request_handler); - - if (_session_requests.constructed()) - _handle_session_requests(); } + /* + * Try to resolve pending session requests that may become serviceable with + * the new configuration. + */ + if (services_provided && _session_requests.constructed()) + _handle_session_requests(); + /* * Re-validate routes of existing sessions, close sessions whose routes * changed. @@ -375,6 +390,7 @@ void Init::Server::apply_config(Xml_node config) if (!route_unchanged) throw Service_denied(); } - catch (Service_denied) { close_session(session); } + catch (Service_denied) { close_session(session); } + catch (Service_not_present) { close_session(session); } }); } diff --git a/repos/os/src/init/server.h b/repos/os/src/init/server.h index ef908bdc57..93b079380a 100644 --- a/repos/os/src/init/server.h +++ b/repos/os/src/init/server.h @@ -51,6 +51,11 @@ class Init::Server : Session_state::Ready_callback, */ Id_space _client_id_space; + /** + * Exception type + */ + class Service_not_present : Exception { }; + /** * Meta data of service provided to our parent */