From a9183da87b001bb14cb8a7fbec0763334ef0ffbf Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 19 Jun 2018 16:09:39 +0200 Subject: [PATCH] base: create-after-close session-request order This patch ensures that session-create requests are handled after close requests, which solves the corner case where one single-session server receives a close and create request at the same time. E.g., when expanding a partition with Sculpt, the gpt-write tool is removed and part_blk is started (to execute resize2fs on top) in one step. Both interact with the USB-block driver, which is a single-session server. Fixes #2877 --- repos/base/src/lib/base/root_proxy.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/repos/base/src/lib/base/root_proxy.cc b/repos/base/src/lib/base/root_proxy.cc index 199f0c9e05..a4a5d8d480 100644 --- a/repos/base/src/lib/base/root_proxy.cc +++ b/repos/base/src/lib/base/root_proxy.cc @@ -127,7 +127,7 @@ namespace { Tslab _session_slab { &_sliced_heap }; - void _handle_session_request(Xml_node); + void _handle_session_request(Xml_node, char const *type); void _handle_session_requests(); Service_registry _services { }; @@ -153,9 +153,9 @@ namespace { } -void Root_proxy::_handle_session_request(Xml_node request) +void Root_proxy::_handle_session_request(Xml_node request, char const *type) { - if (!request.has_attribute("id")) + if (!request.has_attribute("id") || !request.has_type(type)) return; Parent::Server::Id const id { request.attribute_value("id", 0UL) }; @@ -226,8 +226,22 @@ void Root_proxy::_handle_session_requests() Xml_node const requests = _session_requests.xml(); + /* + * Make sure to hande create requests after close requests. Otherwise, a + * single-session server (like a block driver) may fail to handle a + * situation where one session (of a disappearing client) is closed and a + * new session (by a freshly appearing client) is created in one atomic + * step. If we served the new client before the old one, it would look like + * an attempt to create a second session. + */ requests.for_each_sub_node([&] (Xml_node request) { - _handle_session_request(request); }); + _handle_session_request(request, "upgrade"); }); + + requests.for_each_sub_node([&] (Xml_node request) { + _handle_session_request(request, "close"); }); + + requests.for_each_sub_node([&] (Xml_node request) { + _handle_session_request(request, "create"); }); }