From 028e633af4cf70dcfbde87edfbd09d83f2cfd30d Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 8 May 2017 19:47:12 +0200 Subject: [PATCH] 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 --- repos/base/include/base/session_object.h | 120 +++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 repos/base/include/base/session_object.h diff --git a/repos/base/include/base/session_object.h b/repos/base/include/base/session_object.h new file mode 100644 index 0000000000..78943e211e --- /dev/null +++ b/repos/base/include/base/session_object.h @@ -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 +#include +#include + +namespace Genode { template struct Session_object; } + +template +class Genode::Session_object : public Ram_quota_guard, + public Cap_quota_guard, + public Rpc_object +{ + 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 + void diag(ARGS &&... args) + { + if (_diag.enabled) + log(RPC_INTERFACE::service_name(), " (", _label, ") ", args...); + } + + /** + * Output label-prefixed error message + */ + template + void error(ARGS &&... args) + { + Genode::error(RPC_INTERFACE::service_name(), " (", _label, ") ", args...); + } + + /** + * Output label-prefixed error message + */ + template + void warning(ARGS &&... args) + { + Genode::warning(RPC_INTERFACE::service_name(), " (", _label, ") ", args...); + } +}; + +#endif /* _INCLUDE__BASE__SESSION_OBJECT_H_ */