diff --git a/repos/base/src/core/include/rm_session_component.h b/repos/base/src/core/include/rm_session_component.h index fbf905f8ed..86c26a38f8 100644 --- a/repos/base/src/core/include/rm_session_component.h +++ b/repos/base/src/core/include/rm_session_component.h @@ -36,12 +36,6 @@ class Genode::Rm_session_component : public Rpc_object Lock _region_maps_lock; List _region_maps; - void _destroy(Region_map_component &rmc) - { - _region_maps.remove(&rmc); - Genode::destroy(_md_alloc, &rmc); - } - public: /** @@ -59,8 +53,10 @@ class Genode::Rm_session_component : public Rpc_object { Lock::Guard guard(_region_maps_lock); - while (Region_map_component *rmc = _region_maps.first()) - _destroy(*rmc); + while (Region_map_component *rmc = _region_maps.first()) { + _region_maps.remove(rmc); + Genode::destroy(_md_alloc, rmc); + } } /** @@ -89,18 +85,24 @@ class Genode::Rm_session_component : public Rpc_object catch (Allocator::Out_of_memory) { throw Out_of_metadata(); } } - void destroy(Capability rm) override + void destroy(Capability cap) override { Lock::Guard guard(_region_maps_lock); - _ep.apply(rm, [&] (Region_map_component *rmc) { + Region_map_component *rm = nullptr; + + _ep.apply(cap, [&] (Region_map_component *rmc) { if (!rmc) { warning("could not look up region map to destruct"); return; } - _destroy(*rmc); + _region_maps.remove(rmc); + rm = rmc; }); + + if (rm) + Genode::destroy(_md_alloc, rm); } }; diff --git a/repos/base/src/test/rm_nested/main.cc b/repos/base/src/test/rm_nested/main.cc index 8e3e7a717a..101107f114 100644 --- a/repos/base/src/test/rm_nested/main.cc +++ b/repos/base/src/test/rm_nested/main.cc @@ -120,6 +120,10 @@ int main(int argc, char **argv) receiver.dissolve(&context); - printf("--- finished nested region map test ---\n"); + log("test destruction of region_map"); + Capability rcap = rm.create(4096); + rm.destroy(rcap); + + log("--- finished nested region map test ---"); return 0; } diff --git a/repos/base/src/test/sub_rm/main.cc b/repos/base/src/test/sub_rm/main.cc index a0261b4e9c..7eb5fc770f 100644 --- a/repos/base/src/test/sub_rm/main.cc +++ b/repos/base/src/test/sub_rm/main.cc @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include @@ -40,13 +40,13 @@ static char const *test_pattern_2() { return "A second pattern to verify dataspace content"; } -static void fill_ds_with_test_pattern(char const *pattern, +static void fill_ds_with_test_pattern(Env &env, char const *pattern, Dataspace_capability ds, size_t offset) { log("fill dataspace with information"); - char *content = env()->rm_session()->attach(ds); + char *content = env.rm().attach(ds); strncpy(content + offset, pattern, ~0); - env()->rm_session()->detach(content); + env.rm().detach(content); } @@ -57,24 +57,37 @@ static void validate_pattern_at(char const *pattern, char const *ptr) } -int main(int, char **) +void Component::construct(Env &env) { log("--- sub-rm test ---"); log("create RM connection"); enum { SUB_RM_SIZE = 1024*1024 }; - Rm_connection rm; + Rm_connection rm(env); + /* + * Free and re-allocate the region map to excersize the 'destroy' + * operation. + */ + { + log("create and destroy region map"); + Capability rm_cap = rm.create(SUB_RM_SIZE); + rm.destroy(rm_cap); + } + + /* + * Create region cap to be used for the actual test + */ + log("create managed dataspace"); Region_map_client sub_rm(rm.create(SUB_RM_SIZE)); - enum { DS_SIZE = 4*4096 }; - Ram_dataspace_capability ds = env()->ram_session()->alloc(DS_SIZE); + Ram_dataspace_capability ds = env.ram().alloc(DS_SIZE); /* * Write test patterns to the start and the second page of the RAM ds */ - fill_ds_with_test_pattern(test_pattern(), ds, 0); - fill_ds_with_test_pattern(test_pattern_2(), ds, 4096); + fill_ds_with_test_pattern(env, test_pattern(), ds, 0); + fill_ds_with_test_pattern(env, test_pattern_2(), ds, 4096); if (!support_attach_sub_any) { log("attach RAM ds to any position at sub rm - this should fail"); @@ -103,8 +116,8 @@ int main(int, char **) * vdso page to this location. reason ... keeping fingers crossed. */ enum { LOCAL_ATTACH_ADDR = 0x60000000 }; - char *sub_rm_base = env()->rm_session()->attach_at(sub_rm.dataspace(), - LOCAL_ATTACH_ADDR); + char *sub_rm_base = env.rm().attach_at(sub_rm.dataspace(), + LOCAL_ATTACH_ADDR); log("validate pattern in sub rm"); validate_pattern_at(test_pattern(), sub_rm_base + DS_SUB_OFFSET); @@ -150,7 +163,7 @@ int main(int, char **) */ log("attach sub rm again at local address space"); try { - env()->rm_session()->attach(sub_rm.dataspace()); + env.rm().attach(sub_rm.dataspace()); fail("double attachment of sub RM session went undetected\n"); } catch (Region_map::Out_of_metadata) { @@ -190,5 +203,5 @@ int main(int, char **) * memory mappings after completing the test. */ sleep_forever(); - return 0; + }