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
This commit is contained in:
Norman Feske 2024-08-14 15:14:33 +02:00 committed by Christian Helmuth
parent faf90f259c
commit d762da8659
12 changed files with 36 additions and 18 deletions

View File

@ -133,7 +133,7 @@ struct Gui::Session_component : Rpc_object<Gui::Session>
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 {

View File

@ -138,7 +138,7 @@ struct Sandboxed_runtime::Gui_session : Session_object<Gui::Session>
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 {

View File

@ -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);
}

View File

@ -298,7 +298,7 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object<Gui::Session>,
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);
}

View File

@ -88,7 +88,7 @@ class Wm::Direct_gui_session : public Genode::Rpc_object<Gui::Session>
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);
}

View File

@ -225,7 +225,11 @@ class Wm::Gui::View : private Genode::Weak_object<View>,
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>(
[&] (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<Top_level_view>::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<Gui::Session>,
});
}
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(); },

View File

@ -79,7 +79,7 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object<Gui::Session>
return Associate_result::OK;
}
View_capability view_capability(View_id) override
View_capability_result view_capability(View_id) override
{
return View_capability();
}

View File

@ -42,7 +42,7 @@ struct Gui::Session_client : Rpc_client<Session>
Associate_result associate(View_id id, View_capability view) override {
return call<Rpc_associate>(id, view); }
View_capability view_capability(View_id id) override {
View_capability_result view_capability(View_id id) override {
return call<Rpc_view_capability>(id); }
void release_view_id(View_id id) override {

View File

@ -110,7 +110,21 @@ class Gui::Connection : private Genode::Connection<Session>
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<bool>(
[&] (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)

View File

@ -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<View_capability, View_capability_error>;
/**
* 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);

View File

@ -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(); },

View File

@ -392,7 +392,7 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
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;