wm: prevent superfluous session upgrades

For each session upgrade performed by a wm client as part of the
Nitpicker::Connection::buffer function, the window manager wrongly
upgraded the wrapped nitpicker session twice: Once by handling the
Root::upgrade, and again by handling of the server-side 'buffer'
operation. Here, the 'buffer' operation was implemented by not merely
forwarding the RPC request to the wrapped nitpicker session but by
calling the 'buffer' method on the wrapped session's connection
object, which implictly issues session upgrades. Consequently,
the window manager would transfer twice the amount of the session
upgrades it received by its clients to nitpicker and eventually ran
out of memory.

The patch fixes the problem by eliminating the call of the
Nitpicker::Connection::buffer method and instead merely forward the RPC
requests to the wrapped nitpicker sessions.
This commit is contained in:
Norman Feske 2015-11-21 10:22:11 +01:00 committed by Christian Helmuth
parent 461776a29c
commit 493386ed27
2 changed files with 15 additions and 2 deletions

View File

@ -447,7 +447,10 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
void buffer(Framebuffer::Mode mode, bool use_alpha) override
{
_nitpicker_session.buffer(mode, use_alpha);
/*
* See comment in 'Wm::Nitpicker::Session_component::buffer'.
*/
Nitpicker::Session_client(_nitpicker_session.cap()).buffer(mode, use_alpha);
}
void focus(Genode::Capability<Nitpicker::Session>) { }

View File

@ -942,7 +942,17 @@ class Wm::Nitpicker::Session_component : public Rpc_object<Nitpicker::Session>,
void buffer(Framebuffer::Mode mode, bool has_alpha) override
{
_session.buffer(mode, has_alpha);
/*
* We must not perform the 'buffer' operation on the connection
* object because the 'Nitpicker::Connection::buffer'
* implementation implicitly performs upgrade operations.
*
* Here, we merely want to forward the buffer RPC call to the
* wrapped nitpicker session. Otherwise, we would perform
* session upgrades initiated by the wm client's buffer
* operation twice.
*/
Nitpicker::Session_client(_session.cap()).buffer(mode, has_alpha);
_has_alpha = has_alpha;
}