base: add 'Session_object' class

The 'Session_object' unifies several aspects of server-component
implementations:

* It keeps track of session quotas and is equipped with standardized
  interfaces (Quota_guard) to upgrade (and in the future potentially
  downgrade) session quotas in a uniform way.

* It follows the pattern of modern RPC objects / signal handlers that
  manage/dissolve themselves at the entrypoint given as constructor
  argument. Thereby, the relationship with its entrypoint is always
  coupled with the lifetime of the session-component object.

* It stores the session label, which was previously done manually by
  most but not all server-component implementations.

* It stores the session 'diag' flag.

* It is equipped with output methods 'diag', 'error', and 'warning'.
  All messages printed from the context of a session component is
  automatically prefixed with the session type and client label.
  Messages passed via 'diag' are only printed if the 'diag' flag of
  the session is set.

Issue #2398
This commit is contained in:
Norman Feske 2017-05-08 19:47:12 +02:00 committed by Christian Helmuth
parent aea5d03691
commit 028e633af4

View File

@ -0,0 +1,120 @@
/*
* \brief RPC object that owns client-provided RAM and capability quotas
* \author Norman Feske
* \date 2017-04-28
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__BASE__SESSION_OBJECT_H_
#define _INCLUDE__BASE__SESSION_OBJECT_H_
#include <util/arg_string.h>
#include <base/entrypoint.h>
#include <session/session.h>
namespace Genode { template <typename, typename> struct Session_object; }
template <typename RPC_INTERFACE, typename SERVER = RPC_INTERFACE>
class Genode::Session_object : public Ram_quota_guard,
public Cap_quota_guard,
public Rpc_object<RPC_INTERFACE, SERVER>
{
public:
typedef Session::Label Label;
typedef Session::Diag Diag;
typedef Session::Resources Resources;
private:
Rpc_entrypoint &_ep;
Diag _diag;
protected:
Label const _label;
public:
/**
* Constructor
*/
Session_object(Entrypoint &ep, Resources const &resources,
Label const &label, Diag diag)
:
Session_object(ep.rpc_ep(), resources, label, diag)
{ }
/**
* Constructor
*
* \deprecated This constructor exists for backward compatibility only
* and will eventually be removed.
*/
Session_object(Rpc_entrypoint &ep, Resources const &resources,
Label const &label, Diag diag)
:
Ram_quota_guard(resources.ram_quota),
Cap_quota_guard(resources.cap_quota),
_ep(ep), _diag(diag), _label(label)
{
Cap_quota_guard::withdraw(Cap_quota{1});
_ep.manage(this);
}
~Session_object()
{
_ep.dissolve(this);
Cap_quota_guard::replenish(Cap_quota{1});
}
/**
* Hook called whenever the session quota was upgraded by the client
*/
virtual void session_quota_upgraded() { }
/**
* Return client-specific session label
*/
Label label() const { return _label; }
/**
* Output label-prefixed diagnostic message conditionally
*
* The method produces output only if the session is in diagnostic
* mode (defined via the 'diag' session argument).
*/
template <typename... ARGS>
void diag(ARGS &&... args)
{
if (_diag.enabled)
log(RPC_INTERFACE::service_name(), " (", _label, ") ", args...);
}
/**
* Output label-prefixed error message
*/
template <typename... ARGS>
void error(ARGS &&... args)
{
Genode::error(RPC_INTERFACE::service_name(), " (", _label, ") ", args...);
}
/**
* Output label-prefixed error message
*/
template <typename... ARGS>
void warning(ARGS &&... args)
{
Genode::warning(RPC_INTERFACE::service_name(), " (", _label, ") ", args...);
}
};
#endif /* _INCLUDE__BASE__SESSION_OBJECT_H_ */