mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-02 07:30:58 +00:00
base: drop session states of vanished clients
For asynchronously provided sessions, the parent has to maintain the session state as long as the server hasn't explicitly responded to a close request. For this reason, the lifetime of such session states is bound to the server, not the client. When the server responds to a close request, the session state gets freed. The 'session_response' implementation does not immediately destroy the session state but delegates the destruction to a client-side callback, which thereby also notifies the client. However, the code did not consider the case where the client has completely vanished at session-response time. In this case, we need to drop the session state immediately. Fixes #2391
This commit is contained in:
parent
76bc2b9e89
commit
8e7aa54493
@ -533,8 +533,17 @@ void Child::session_response(Server::Id id, Session_response response)
|
|||||||
|
|
||||||
case Parent::SESSION_CLOSED:
|
case Parent::SESSION_CLOSED:
|
||||||
session.phase = Session_state::CLOSED;
|
session.phase = Session_state::CLOSED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the client exists, reflect the response to the client
|
||||||
|
* via the 'closed_callback'. If the client has vanished,
|
||||||
|
* i.e., if the close request was issued by ourself while
|
||||||
|
* killing a child, we drop the session state immediately.
|
||||||
|
*/
|
||||||
if (session.closed_callback)
|
if (session.closed_callback)
|
||||||
session.closed_callback->session_closed(session);
|
session.closed_callback->session_closed(session);
|
||||||
|
else
|
||||||
|
_revert_quota_and_destroy(session);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Parent::INVALID_ARGS:
|
case Parent::INVALID_ARGS:
|
||||||
|
@ -92,6 +92,12 @@ append config {
|
|||||||
|
|
||||||
<message string="routing to custom log service"/>
|
<message string="routing to custom log service"/>
|
||||||
|
|
||||||
|
<!-- We let the client manually create a LOG session in addition
|
||||||
|
to its env LOG session. So there are two sessions at the
|
||||||
|
server, one initiated by init and one initiated by the
|
||||||
|
child. Both cases trigger distinct code paths at child-
|
||||||
|
destruction time. -->
|
||||||
|
|
||||||
<init_config version="chained log services">
|
<init_config version="chained log services">
|
||||||
<report ids="yes" requested="yes" provided="yes"/>
|
<report ids="yes" requested="yes" provided="yes"/>
|
||||||
<parent-provides>
|
<parent-provides>
|
||||||
@ -121,7 +127,10 @@ append config {
|
|||||||
<start name="client">
|
<start name="client">
|
||||||
<binary name="dummy"/>
|
<binary name="dummy"/>
|
||||||
<resource name="RAM" quantum="1M"/>
|
<resource name="RAM" quantum="1M"/>
|
||||||
<config> <log string="client started"/> </config>
|
<config>
|
||||||
|
<log string="client started"/>
|
||||||
|
<create_log_connections count="1"/>
|
||||||
|
</config>
|
||||||
<route>
|
<route>
|
||||||
<service name="LOG"> <child name="indirect_server"/> </service>
|
<service name="LOG"> <child name="indirect_server"/> </service>
|
||||||
<any-service> <parent/> </any-service>
|
<any-service> <parent/> </any-service>
|
||||||
@ -177,7 +186,10 @@ append config {
|
|||||||
<start name="client">
|
<start name="client">
|
||||||
<binary name="dummy"/>
|
<binary name="dummy"/>
|
||||||
<resource name="RAM" quantum="1M"/>
|
<resource name="RAM" quantum="1M"/>
|
||||||
<config> <log string="client started"/> </config>
|
<config>
|
||||||
|
<log string="client started"/>
|
||||||
|
<create_log_connections count="1"/>
|
||||||
|
</config>
|
||||||
<route>
|
<route>
|
||||||
<service name="LOG"> <child name="indirect_server"/> </service>
|
<service name="LOG"> <child name="indirect_server"/> </service>
|
||||||
<any-service> <parent/> </any-service>
|
<any-service> <parent/> </any-service>
|
||||||
@ -199,6 +211,44 @@ append config {
|
|||||||
</expect_init_state>
|
</expect_init_state>
|
||||||
<sleep ms="100"/>
|
<sleep ms="100"/>
|
||||||
|
|
||||||
|
<!-- Kill the client and validate that all session states are freed -->
|
||||||
|
|
||||||
|
<init_config version="client removed">
|
||||||
|
<report ids="yes" requested="yes" provided="yes"/>
|
||||||
|
<parent-provides>
|
||||||
|
<service name="ROM"/>
|
||||||
|
<service name="RAM"/>
|
||||||
|
<service name="CPU"/>
|
||||||
|
<service name="PD"/>
|
||||||
|
<service name="LOG"/>
|
||||||
|
</parent-provides>
|
||||||
|
<start name="server">
|
||||||
|
<binary name="dummy"/>
|
||||||
|
<resource name="RAM" quantum="1M"/>
|
||||||
|
<provides> <service name="LOG"/> </provides>
|
||||||
|
<config> <log_service/> </config>
|
||||||
|
<route> <any-service> <parent/> </any-service> </route>
|
||||||
|
</start>
|
||||||
|
<start name="indirect_server">
|
||||||
|
<binary name="dummy"/>
|
||||||
|
<resource name="RAM" quantum="1M"/>
|
||||||
|
<provides> <service name="LOG"/> </provides>
|
||||||
|
<config> <log_service/> </config>
|
||||||
|
<route> <any-service> <parent/> </any-service> </route>
|
||||||
|
</start>
|
||||||
|
</init_config>
|
||||||
|
<sleep ms="150"/>
|
||||||
|
<expect_init_state>
|
||||||
|
<node name="child">
|
||||||
|
<attribute name="name" value="indirect_server"/>
|
||||||
|
<node name="provided">
|
||||||
|
<not>
|
||||||
|
<node name="session"/>
|
||||||
|
</not>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</expect_init_state>
|
||||||
|
|
||||||
|
|
||||||
<message string="test changing provided services"/>
|
<message string="test changing provided services"/>
|
||||||
|
|
||||||
|
@ -91,6 +91,9 @@ static inline bool Test::xml_matches(Xml_node expected, Xml_node node)
|
|||||||
|
|
||||||
matches = matches && at_least_one_sub_node_matches;
|
matches = matches && at_least_one_sub_node_matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (condition.type() == "not")
|
||||||
|
matches = matches && !xml_matches(condition, node);
|
||||||
});
|
});
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user