From 5181d08d05038124ba988fcff848f1ddb0015aea Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sun, 16 Jun 2024 15:08:56 +0200 Subject: [PATCH] Remove exceptions from Rm_session interface Issue #5245 --- .../include/base/internal/local_rm_session.h | 10 ++++-- .../src/lib/base/rm_session_client.cc | 2 +- repos/base/include/region_map/region_map.h | 1 + repos/base/include/rm_session/client.h | 2 +- repos/base/include/rm_session/connection.h | 36 ++++++++++--------- repos/base/include/rm_session/rm_session.h | 10 +++--- .../src/core/include/rm_session_component.h | 5 +-- repos/base/src/lib/base/rm_session_client.cc | 2 +- 8 files changed, 39 insertions(+), 29 deletions(-) diff --git a/repos/base-linux/src/include/base/internal/local_rm_session.h b/repos/base-linux/src/include/base/internal/local_rm_session.h index 7265fc0cce..87c1dda141 100644 --- a/repos/base-linux/src/include/base/internal/local_rm_session.h +++ b/repos/base-linux/src/include/base/internal/local_rm_session.h @@ -38,10 +38,14 @@ struct Genode::Local_rm_session : Rm_session, Local_session _local_rm(local_rm), _md_alloc(md_alloc) { } - Capability create(size_t size) override + Create_result create(size_t size) override { - Region_map *rm = new (_md_alloc) Region_map_mmap(true, size); - return Local_capability::local_cap(rm); + try { + Region_map *rm = new (_md_alloc) Region_map_mmap(true, size); + return Local_capability::local_cap(rm); + } + catch (Out_of_ram) { return Create_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Create_error::OUT_OF_CAPS; } } void destroy(Capability cap) override diff --git a/repos/base-linux/src/lib/base/rm_session_client.cc b/repos/base-linux/src/lib/base/rm_session_client.cc index eefecc08c2..bc44619e46 100644 --- a/repos/base-linux/src/lib/base/rm_session_client.cc +++ b/repos/base-linux/src/lib/base/rm_session_client.cc @@ -35,7 +35,7 @@ Rm_session_client::Rm_session_client(Capability session) : Rpc_client(session) { } -Capability Rm_session_client::create(size_t size) { +Rm_session::Create_result Rm_session_client::create(size_t size) { return _local(rpc_cap())->create(size); } diff --git a/repos/base/include/region_map/region_map.h b/repos/base/include/region_map/region_map.h index c98da7ce3f..e068e3d7db 100644 --- a/repos/base/include/region_map/region_map.h +++ b/repos/base/include/region_map/region_map.h @@ -14,6 +14,7 @@ #ifndef _INCLUDE__REGION_MAP__REGION_MAP_H_ #define _INCLUDE__REGION_MAP__REGION_MAP_H_ +#include #include #include #include diff --git a/repos/base/include/rm_session/client.h b/repos/base/include/rm_session/client.h index 47434e5afa..14a84dd558 100644 --- a/repos/base/include/rm_session/client.h +++ b/repos/base/include/rm_session/client.h @@ -24,7 +24,7 @@ struct Genode::Rm_session_client : Rpc_client { explicit Rm_session_client(Rm_session_capability); - Capability create(size_t) override; + Create_result create(size_t) override; void destroy(Capability) override; }; diff --git a/repos/base/include/rm_session/connection.h b/repos/base/include/rm_session/connection.h index 0ef432bf7c..365eff278a 100644 --- a/repos/base/include/rm_session/connection.h +++ b/repos/base/include/rm_session/connection.h @@ -21,31 +21,35 @@ namespace Genode { struct Rm_connection; } -struct Genode::Rm_connection : Connection, Rm_session_client +struct Genode::Rm_connection : Connection { + Rm_session_client _client { cap() }; + Rm_connection(Env &env) : - Connection(env, Label(), Ram_quota { 64*1024 }, Args()), - Rm_session_client(cap()) + Connection(env, {}, Ram_quota { 64*1024 }, Args()) { } /** - * Wrapper over 'create' that handles resource requests from the server + * Wrapper of 'create' that handles session-quota upgrades on demand */ - Capability create(size_t size) override + Capability create(size_t size) { - enum { UPGRADE_ATTEMPTS = 16U }; - - return Genode::retry( - [&] () { - return Genode::retry( - [&] () { return Rm_session_client::create(size); }, - [&] () { upgrade_caps(2); }, - UPGRADE_ATTEMPTS); - }, - [&] () { upgrade_ram(8*1024); }, - UPGRADE_ATTEMPTS); + Capability result { }; + using Error = Rm_session::Create_error; + while (!result.valid()) + _client.create(size).with_result( + [&] (Capability cap) { result = cap; }, + [&] (Error e) { + switch (e) { + case Error::OUT_OF_RAM: upgrade_ram(8*1024); break; + case Error::OUT_OF_CAPS: upgrade_caps(2); break; + } + }); + return result; } + + void destroy(Capability cap) { _client.destroy(cap); } }; #endif /* _INCLUDE__RM_SESSION__CONNECTION_H_ */ diff --git a/repos/base/include/rm_session/rm_session.h b/repos/base/include/rm_session/rm_session.h index 58174e7993..f119455ee3 100644 --- a/repos/base/include/rm_session/rm_session.h +++ b/repos/base/include/rm_session/rm_session.h @@ -33,15 +33,16 @@ struct Genode::Rm_session : Session */ enum { CAP_QUOTA = 2 }; + enum class Create_error { OUT_OF_RAM, OUT_OF_CAPS }; + using Create_result = Attempt, Create_error>; + /** * Create region map * * \param size upper bound of region map * \return region-map capability - * \throw Out_of_ram - * \throw Out_of_caps */ - virtual Capability create(size_t size) = 0; + virtual Create_result create(size_t size) = 0; /** * Destroy region map @@ -53,8 +54,7 @@ struct Genode::Rm_session : Session ** RPC declaration ** *********************/ - GENODE_RPC_THROW(Rpc_create, Capability, create, - GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), size_t); + GENODE_RPC(Rpc_create, Create_result, create, size_t); GENODE_RPC(Rpc_destroy, void, destroy, Capability); GENODE_RPC_INTERFACE(Rpc_create, Rpc_destroy); diff --git a/repos/base/src/core/include/rm_session_component.h b/repos/base/src/core/include/rm_session_component.h index c3731b0f61..2621ab0c45 100644 --- a/repos/base/src/core/include/rm_session_component.h +++ b/repos/base/src/core/include/rm_session_component.h @@ -72,7 +72,7 @@ class Core::Rm_session_component : public Session_object ** Rm_session interface ** **************************/ - Capability create(size_t size) override + Create_result create(size_t size) override { Mutex::Guard guard(_region_maps_lock); @@ -86,7 +86,8 @@ class Core::Rm_session_component : public Session_object return rm->cap(); } - catch (Allocator::Out_of_memory) { throw Out_of_ram(); } + catch (Out_of_ram) { return Create_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Create_error::OUT_OF_CAPS; } } void destroy(Capability cap) override diff --git a/repos/base/src/lib/base/rm_session_client.cc b/repos/base/src/lib/base/rm_session_client.cc index 835b7399d1..25b4c74d26 100644 --- a/repos/base/src/lib/base/rm_session_client.cc +++ b/repos/base/src/lib/base/rm_session_client.cc @@ -20,7 +20,7 @@ Rm_session_client::Rm_session_client(Capability cap) : Rpc_client(cap) { } -Capability Rm_session_client::create(size_t size) { +Rm_session::Create_result Rm_session_client::create(size_t size) { return call(size); }