From d762da8659a67ba9058867a9dc3888e354c9af40 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 14 Aug 2024 15:14:33 +0200 Subject: [PATCH] gui_session: allow return of View_capbility_error This interface change gives GUI servers the freedom to allocate view capabilities at the time of request instead of the creation time of the view. This is useful because view capabilities are rarely needed. Issue #5242 --- repos/gems/src/app/sculpt_manager/gui.cc | 2 +- repos/gems/src/lib/dialog/sandboxed_runtime.cc | 2 +- repos/gems/src/server/gui_fader/main.cc | 2 +- repos/gems/src/server/wm/decorator_gui.h | 2 +- repos/gems/src/server/wm/direct_gui.h | 2 +- repos/gems/src/server/wm/gui.h | 13 +++++++------ repos/gems/src/server/wm/layouter_gui.h | 2 +- repos/os/include/gui_session/client.h | 2 +- repos/os/include/gui_session/connection.h | 16 +++++++++++++++- repos/os/include/gui_session/gui_session.h | 7 +++++-- repos/os/src/server/nitpicker/gui_session.cc | 2 +- repos/os/src/server/nitpicker/gui_session.h | 2 +- 12 files changed, 36 insertions(+), 18 deletions(-) diff --git a/repos/gems/src/app/sculpt_manager/gui.cc b/repos/gems/src/app/sculpt_manager/gui.cc index 1372fdd33b..0174dbb385 100644 --- a/repos/gems/src/app/sculpt_manager/gui.cc +++ b/repos/gems/src/app/sculpt_manager/gui.cc @@ -133,7 +133,7 @@ struct Gui::Session_component : Rpc_object Associate_result associate(View_id id, View_capability view_cap) override { return _gui_session.associate(id, view_cap); } - View_capability view_capability(View_id view) override { + View_capability_result view_capability(View_id view) override { return _gui_session.view_capability(view); } void release_view_id(View_id view) override { diff --git a/repos/gems/src/lib/dialog/sandboxed_runtime.cc b/repos/gems/src/lib/dialog/sandboxed_runtime.cc index 46d222dc97..ff460a3ad8 100644 --- a/repos/gems/src/lib/dialog/sandboxed_runtime.cc +++ b/repos/gems/src/lib/dialog/sandboxed_runtime.cc @@ -138,7 +138,7 @@ struct Sandboxed_runtime::Gui_session : Session_object Associate_result associate(View_id id, View_capability view_cap) override { return _gui_session.associate(id, view_cap); } - View_capability view_capability(View_id view) override { + View_capability_result view_capability(View_id view) override { return _gui_session.view_capability(view); } void release_view_id(View_id view) override { diff --git a/repos/gems/src/server/gui_fader/main.cc b/repos/gems/src/server/gui_fader/main.cc index 5edcac3d81..e6225e2df7 100644 --- a/repos/gems/src/server/gui_fader/main.cc +++ b/repos/gems/src/server/gui_fader/main.cc @@ -372,7 +372,7 @@ class Gui_fader::Gui_session_component return Associate_result::OK; } - View_capability view_capability(View_id id) override + View_capability_result view_capability(View_id id) override { return _gui.view_capability(id); } diff --git a/repos/gems/src/server/wm/decorator_gui.h b/repos/gems/src/server/wm/decorator_gui.h index 097f4341bb..394b289392 100644 --- a/repos/gems/src/server/wm/decorator_gui.h +++ b/repos/gems/src/server/wm/decorator_gui.h @@ -298,7 +298,7 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, return _gui.session.associate(id, view_cap); } - View_capability view_capability(View_id view) override + View_capability_result view_capability(View_id view) override { return _gui.session.view_capability(view); } diff --git a/repos/gems/src/server/wm/direct_gui.h b/repos/gems/src/server/wm/direct_gui.h index d55a33c411..d1080a126b 100644 --- a/repos/gems/src/server/wm/direct_gui.h +++ b/repos/gems/src/server/wm/direct_gui.h @@ -88,7 +88,7 @@ class Wm::Direct_gui_session : public Genode::Rpc_object return _session.associate(id, view_cap); } - View_capability view_capability(View_id view) override + View_capability_result view_capability(View_id view) override { return _session.view_capability(view); } diff --git a/repos/gems/src/server/wm/gui.h b/repos/gems/src/server/wm/gui.h index dd05381914..3379749ae4 100644 --- a/repos/gems/src/server/wm/gui.h +++ b/repos/gems/src/server/wm/gui.h @@ -225,7 +225,11 @@ class Wm::Gui::View : private Genode::Weak_object, View_capability real_view_cap() { - return _real_gui.session.view_capability(_real_view.id()); + return _real_gui.session.view_capability(_real_view.id()).convert( + [&] (View_capability cap) { return cap; }, + [&] (Gui::Session::View_capability_error) { + warning("real_view_cap unable to obtain view capability"); + return View_capability(); }); } void buffer_offset(Point buffer_offset) @@ -353,10 +357,7 @@ class Wm::Gui::Top_level_view : public View, private List::Eleme _input_origin_changed_handler.input_origin_changed(); } - View_capability content_view() - { - return _real_gui.session.view_capability(_real_view.id()); - } + View_capability content_view() { return real_view_cap(); } void hidden(bool hidden) { _window_registry.hidden(_win_id, hidden); } @@ -1068,7 +1069,7 @@ class Wm::Gui::Session_component : public Rpc_object, }); } - View_capability view_capability(View_id id) override + View_capability_result view_capability(View_id id) override { return _with_view(id, [&] (View &view) { return view.cap(); }, diff --git a/repos/gems/src/server/wm/layouter_gui.h b/repos/gems/src/server/wm/layouter_gui.h index d89ada1000..4878a56a23 100644 --- a/repos/gems/src/server/wm/layouter_gui.h +++ b/repos/gems/src/server/wm/layouter_gui.h @@ -79,7 +79,7 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object return Associate_result::OK; } - View_capability view_capability(View_id) override + View_capability_result view_capability(View_id) override { return View_capability(); } diff --git a/repos/os/include/gui_session/client.h b/repos/os/include/gui_session/client.h index ec8abd9495..37da61b4bd 100644 --- a/repos/os/include/gui_session/client.h +++ b/repos/os/include/gui_session/client.h @@ -42,7 +42,7 @@ struct Gui::Session_client : Rpc_client Associate_result associate(View_id id, View_capability view) override { return call(id, view); } - View_capability view_capability(View_id id) override { + View_capability_result view_capability(View_id id) override { return call(id); } void release_view_id(View_id id) override { diff --git a/repos/os/include/gui_session/connection.h b/repos/os/include/gui_session/connection.h index bcaf749c82..aa59a615b1 100644 --- a/repos/os/include/gui_session/connection.h +++ b/repos/os/include/gui_session/connection.h @@ -110,7 +110,21 @@ class Gui::Connection : private Genode::Connection View_capability view_capability(View_id id) { - return _client.view_capability(id); + for (;;) { + View_capability result { }; + using Error = Session::View_capability_error; + bool const retry = _client.view_capability(id).convert( + [&] (View_capability cap) { result = cap; return false; }, + [&] (Error e) { + switch (e) { + case Error::OUT_OF_CAPS: upgrade_caps(2); return true; + case Error::OUT_OF_RAM: upgrade_ram(8*1024); return true; + } + return false; + }); + if (!retry) + return result; + } } void associate(View_id id, View_capability view) diff --git a/repos/os/include/gui_session/gui_session.h b/repos/os/include/gui_session/gui_session.h index 90bd45920d..2e82d35582 100644 --- a/repos/os/include/gui_session/gui_session.h +++ b/repos/os/include/gui_session/gui_session.h @@ -207,13 +207,16 @@ struct Gui::Session : Genode::Session */ virtual Associate_result associate(View_id, View_capability) = 0; + enum class View_capability_error { OUT_OF_RAM, OUT_OF_CAPS }; + using View_capability_result = Attempt; + /** * Request view capability for a given ID * * The returned view capability can be used to share the view with another * session. */ - virtual View_capability view_capability(View_id) = 0; + virtual View_capability_result view_capability(View_id) = 0; /** * Release session-local view ID @@ -285,7 +288,7 @@ struct Gui::Session : Genode::Session GENODE_RPC(Rpc_child_view, Child_view_result, child_view, View_id, View_id, View_attr const &); GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_id); GENODE_RPC(Rpc_associate, Associate_result, associate, View_id, View_capability); - GENODE_RPC(Rpc_view_capability, View_capability, view_capability, View_id); + GENODE_RPC(Rpc_view_capability, View_capability_result, view_capability, View_id); GENODE_RPC(Rpc_release_view_id, void, release_view_id, View_id); GENODE_RPC(Rpc_command_dataspace, Dataspace_capability, command_dataspace); GENODE_RPC(Rpc_execute, void, execute); diff --git a/repos/os/src/server/nitpicker/gui_session.cc b/repos/os/src/server/nitpicker/gui_session.cc index 08825e82f9..5b1bd1ce69 100644 --- a/repos/os/src/server/nitpicker/gui_session.cc +++ b/repos/os/src/server/nitpicker/gui_session.cc @@ -339,7 +339,7 @@ Gui_session::associate(View_id id, View_capability view_cap) } -View_capability Gui_session::view_capability(View_id id) +Gui_session::View_capability_result Gui_session::view_capability(View_id id) { return _with_view(id, [&] (View &view) { return view.cap(); }, diff --git a/repos/os/src/server/nitpicker/gui_session.h b/repos/os/src/server/nitpicker/gui_session.h index 8315166a4f..1235b51475 100644 --- a/repos/os/src/server/nitpicker/gui_session.h +++ b/repos/os/src/server/nitpicker/gui_session.h @@ -392,7 +392,7 @@ class Nitpicker::Gui_session : public Session_object, Associate_result associate(View_id, View_capability) override; - View_capability view_capability(View_id) override; + View_capability_result view_capability(View_id) override; void release_view_id(View_id) override;