diff --git a/repos/base-foc/src/core/cap_session_component.cc b/repos/base-foc/src/core/cap_session_component.cc index 048016d9f..69d14ef96 100644 --- a/repos/base-foc/src/core/cap_session_component.cc +++ b/repos/base-foc/src/core/cap_session_component.cc @@ -84,13 +84,12 @@ Cap_mapping::Cap_mapping(Native_capability cap, Native_thread_id r) ** Cap_session_component ** *****************************/ -Native_capability Cap_session_component::alloc(Cap_session_component *session, - Native_capability ep) +Native_capability Cap_session_component::alloc(Native_capability ep) { Native_capability cap; if (!ep.valid()) { - PWRN("Invalid cap!"); + PWRN("Invalid reference capability!"); return cap; } @@ -108,7 +107,7 @@ Native_capability Cap_session_component::alloc(Cap_session_component *session, Core_cap_index* idx = static_cast(cap_map()->insert(id)); if (!idx) { - PWRN("Out of capabilities!"); + PWRN("Out of capability indices!"); platform_specific()->cap_id_alloc()->free(id); return cap; } @@ -125,40 +124,51 @@ Native_capability Cap_session_component::alloc(Cap_session_component *session, /* set debugger-name of ipc-gate to thread's name */ Fiasco::l4_debugger_set_object_name(idx->kcap(), ref->pt()->name()); - idx->session(session); + idx->session(this); idx->pt(ref->pt()); - idx->inc(); cap = Native_capability(idx); } catch (Cap_id_allocator::Out_of_ids) { - PERR("Out of IDs"); + PERR("Out of capability ids"); } + /* + * insert valid capabilities into the session's object pool to + * be able to destroy them on session destruction. + * For the construction of core's own threads the related cap session + * doesn't have an allocator set. But this session gets never destroyed + * so this is not an issue. + */ + if (cap.valid() && _md_alloc) + _pool.insert(new (_md_alloc) Entry(cap)); return cap; } -Native_capability Cap_session_component::alloc(Native_capability ep) -{ - return Cap_session_component::alloc(this, ep); -} - - void Cap_session_component::free(Native_capability cap) { using namespace Fiasco; - if (!cap.valid()) - return; + if (!cap.valid()) return; - Core_cap_index* idx = static_cast(cap.idx()); + /* proof whether the capability was created by this cap_session */ + if (static_cast(cap.idx())->session() != this) return; - /* - * check whether this cap_session has created the capability to delete. - */ - if (idx->session() != this) - return; + _pool.apply(cap, [this] (Entry *e) { + if (e) { + _pool.remove(e); + destroy(_md_alloc, e); + } else + PWRN("Could not find capability to be deleted"); + }); +} - idx->dec(); + +Cap_session_component::~Cap_session_component() +{ + _pool.remove_all([this] (Entry *e) { + if (!e) return; + destroy(_md_alloc, e); + }); } @@ -203,7 +213,6 @@ void Genode::Capability_map::remove(Genode::Cap_index* i) if (i) { Core_cap_index* e = static_cast(_tree.first() ? _tree.first()->find_by_id(i->id()) : 0); if (e == i) { - l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP, l4_obj_fpage(i->kcap(), 0, L4_FPAGE_RWX), L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ); diff --git a/repos/base-foc/src/core/include/cap_session_component.h b/repos/base-foc/src/core/include/cap_session_component.h index 495a48580..0a23e52e4 100644 --- a/repos/base-foc/src/core/include/cap_session_component.h +++ b/repos/base-foc/src/core/include/cap_session_component.h @@ -17,23 +17,34 @@ /* Genode includes */ #include #include +#include namespace Genode { class Cap_session_component : public Rpc_object { + private: + + struct Entry : Object_pool::Entry + { + Entry(Native_capability cap) : Object_pool::Entry(cap) {} + }; + + Object_pool _pool; + Allocator *_md_alloc; + public: - Cap_session_component(Allocator *md_alloc, const char *args) {} + Cap_session_component(Allocator *md_alloc, const char *args) + : _md_alloc(md_alloc) {} + + ~Cap_session_component(); void upgrade_ram_quota(size_t ram_quota) { } Native_capability alloc(Native_capability ep); void free(Native_capability cap); - - static Native_capability alloc(Cap_session_component *session, - Native_capability ep); }; } diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index 320173b85..92d4a5402 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -226,8 +226,13 @@ void Platform_thread::_create_thread() if (l4_msgtag_has_error(tag)) PERR("cannot create more thread kernel-objects!"); + /* for core threads we can't use core_env, it is to early */ + static Cap_session_component core_thread_cap_session(0,""); + Cap_session &csc = (_core_thread) + ? core_thread_cap_session : *core_env()->cap_session(); + /* create initial gate for thread */ - _gate.local = Cap_session_component::alloc(0, _thread.local); + _gate.local = csc.alloc(_thread.local); } @@ -311,7 +316,7 @@ Platform_thread::Platform_thread(const char *name) Platform_thread::~Platform_thread() { - _gate.local.idx()->dec(); + core_env()->cap_session()->free(_gate.local); /* * We inform our protection domain about thread destruction, which will end up in