core: fix destruction of dependent CPU sessions

Issue #3578
This commit is contained in:
Norman Feske 2019-12-06 13:35:00 +01:00 committed by Christian Helmuth
parent 298f317f44
commit 4e57b6eceb
2 changed files with 34 additions and 13 deletions

View File

@ -283,21 +283,22 @@ Cpu_session_component::~Cpu_session_component()
void Cpu_session_component::_deinit_ref_account()
{
/* without a ref-account, nothing has do be done */
if (!_ref) { return; }
/* rewire child ref accounts to this sessions's ref account */
{
Lock::Guard lock_guard(_ref_members_lock);
for (Cpu_session_component * s; (s = _ref_members.first()); ) {
_unsync_remove_ref_member(*s);
if (_ref)
_ref->_insert_ref_member(s);
}
}
/* give back our remaining quota to our ref account */
_transfer_quota(*_ref, _quota);
if (_ref) {
/* give back our remaining quota to our ref account */
_transfer_quota(*_ref, _quota);
/* remove ref-account relation between us and our ref-account */
Cpu_session_component * const orig_ref = _ref;
_ref->_remove_ref_member(*this);
/* redirect ref-account relation of ref members to our prior ref account */
Lock::Guard lock_guard(_ref_members_lock);
for (Cpu_session_component * s; (s = _ref_members.first()); ) {
_unsync_remove_ref_member(*s);
orig_ref->_insert_ref_member(s);
/* remove ref-account relation between us and our ref-account */
_ref->_remove_ref_member(*this);
}
}

View File

@ -682,6 +682,23 @@ static void test_successive_create_destroy_threads(Env &env)
}
/******************************************************
** Test destruction of inter-dependent CPU sessions **
******************************************************/
static void test_destroy_dependent_cpu_sessions(Env &env)
{
log("destroy dependent CPU sessions in wrong order");
Cpu_connection grandchild { env };
Cpu_connection child { env };
grandchild.ref_account(child.rpc_cap());
/* when leaving the scope, 'child' is destructed before 'grandchild' */
}
void Component::construct(Env &env)
{
log("--- thread test started ---");
@ -689,6 +706,9 @@ void Component::construct(Env &env)
Attached_rom_dataspace config(env, "config");
try {
test_destroy_dependent_cpu_sessions(env);
test_stack_alloc(env);
test_stack_alignment(env);
test_main_thread();