Support const RPC functions with no arguments

Until now, the RPC framework did not support const RPC functions. Rather
than being a limitation inherent to the concept, const RPC functions
plainly did not exist. So supporting them was not deemed too important.
However, there are uses of RPC interfaces that would benefit from a way
to declare an RPC function as const. Candidates are functions like
'Framebuffer::Session::mode()' and 'Input::Session::is_pending()'.

This patch clears the way towards declaring such functions as const.
Even though the patch is simple enough, the thorough support for
const-qualified RPC functions would double the number of overloads for
the 'call_member' function template (in 'base/include/util/meta.h'). For
this reason, the patch does support const getter functions with no
arguments only. This appears to be the most common use of such
functions.
This commit is contained in:
Norman Feske 2012-01-25 22:33:24 +01:00
parent 83a8e83ae0
commit 210eb98598
3 changed files with 36 additions and 27 deletions

View File

@ -48,32 +48,32 @@ namespace Genode {
* Insert RPC arguments into the message buffer
*/
template <typename ATL>
void _marshal_args(Ipc_client &ipc_client, ATL &args);
void _marshal_args(Ipc_client &ipc_client, ATL &args) const;
void _marshal_args(Ipc_client &, Meta::Empty &) { }
void _marshal_args(Ipc_client &, Meta::Empty &) const { }
/**
* Unmarshal single RPC argument from the message buffer
*/
template <typename T>
void _unmarshal_result(Ipc_client &ipc_client, T &arg,
Meta::Overload_selector<Rpc_arg_out>);
Meta::Overload_selector<Rpc_arg_out>) const;
template <typename T>
void _unmarshal_result(Ipc_client &ipc_client, T &arg,
Meta::Overload_selector<Rpc_arg_inout>);
Meta::Overload_selector<Rpc_arg_inout>) const;
template <typename T>
void _unmarshal_result(Ipc_client &, T &arg,
Meta::Overload_selector<Rpc_arg_in>) { }
Meta::Overload_selector<Rpc_arg_in>) const { }
/**
* Read RPC results from the message buffer
*/
template <typename ATL>
void _unmarshal_results(Ipc_client &ipc_client, ATL &args);
void _unmarshal_results(Ipc_client &ipc_client, ATL &args) const;
void _unmarshal_results(Ipc_client &, Meta::Empty &) { }
void _unmarshal_results(Ipc_client &, Meta::Empty &) const { }
/**
* Check RPC return code for the occurrence of exceptions
@ -86,7 +86,7 @@ namespace Genode {
*/
template <typename EXC_TL>
void _check_for_exceptions(Rpc_exception_code const exc_code,
Meta::Overload_selector<EXC_TL>)
Meta::Overload_selector<EXC_TL>) const
{
enum { EXCEPTION_CODE = RPC_EXCEPTION_BASE - Meta::Length<EXC_TL>::Value };
@ -97,13 +97,15 @@ namespace Genode {
}
void _check_for_exceptions(Rpc_exception_code const,
Meta::Overload_selector<Meta::Empty>) { }
Meta::Overload_selector<Meta::Empty>) const
{ }
/**
* Perform RPC call, arguments passed a as nested 'Ref_tuple' object
*/
template <typename IF>
void _call(typename IF::Client_args &args, typename IF::Ret_type &ret);
void _call(typename IF::Client_args &args,
typename IF::Ret_type &ret) const;
/**
* Shortcut for querying argument types used in 'call' functions
@ -116,7 +118,7 @@ namespace Genode {
template <typename FROM_RPC_INTERFACE>
Untyped_capability
_check_compatibility(Capability<FROM_RPC_INTERFACE> const &cap)
_check_compatibility(Capability<FROM_RPC_INTERFACE> const &cap) const
{
FROM_RPC_INTERFACE *from = 0;
RPC_INTERFACE *to = from;
@ -158,7 +160,7 @@ namespace Genode {
template <typename IF>
typename Trait::Call_return<typename IF::Ret_type>::Type
call()
call() const
{
Meta::Empty e;
typename Trait::Call_return<typename IF::Ret_type>::Type ret;
@ -168,7 +170,7 @@ namespace Genode {
template <typename IF>
typename Trait::Call_return<typename IF::Ret_type>::Type
call(typename Arg<IF, 0>::Type v1)
call(typename Arg<IF, 0>::Type v1) const
{
Meta::Empty e;
typename IF::Client_args args(v1, e);
@ -179,7 +181,7 @@ namespace Genode {
template <typename IF>
typename Trait::Call_return<typename IF::Ret_type>::Type
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2)
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2) const
{
Meta::Empty e;
typename IF::Client_args args(v1, v2, e);
@ -191,7 +193,7 @@ namespace Genode {
template <typename IF>
typename Trait::Call_return<typename IF::Ret_type>::Type
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2,
typename Arg<IF, 2>::Type v3)
typename Arg<IF, 2>::Type v3) const
{
Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, e);
@ -203,7 +205,7 @@ namespace Genode {
template <typename IF>
typename Trait::Call_return<typename IF::Ret_type>::Type
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2,
typename Arg<IF, 2>::Type v3, typename Arg<IF, 3>::Type v4)
typename Arg<IF, 2>::Type v3, typename Arg<IF, 3>::Type v4) const
{
Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, e);
@ -216,7 +218,7 @@ namespace Genode {
typename Trait::Call_return<typename IF::Ret_type>::Type
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2,
typename Arg<IF, 2>::Type v3, typename Arg<IF, 3>::Type v4,
typename Arg<IF, 4>::Type v5)
typename Arg<IF, 4>::Type v5) const
{
Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, v5, e);
@ -229,7 +231,7 @@ namespace Genode {
typename Trait::Call_return<typename IF::Ret_type>::Type
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2,
typename Arg<IF, 2>::Type v3, typename Arg<IF, 3>::Type v4,
typename Arg<IF, 4>::Type v5, typename Arg<IF, 5>::Type v6)
typename Arg<IF, 4>::Type v5, typename Arg<IF, 5>::Type v6) const
{
Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, v5, v6, e);
@ -243,7 +245,7 @@ namespace Genode {
call(typename Arg<IF, 0>::Type v1, typename Arg<IF, 1>::Type v2,
typename Arg<IF, 2>::Type v3, typename Arg<IF, 3>::Type v4,
typename Arg<IF, 4>::Type v5, typename Arg<IF, 5>::Type v6,
typename Arg<IF, 6>::Type v7)
typename Arg<IF, 6>::Type v7) const
{
Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, v5, v6, v7, e);

View File

@ -45,7 +45,7 @@ namespace Genode {
template <typename RPC_INTERFACE>
template <typename ATL>
void Capability<RPC_INTERFACE>::
_marshal_args(Ipc_client &ipc_client, ATL &args)
_marshal_args(Ipc_client &ipc_client, ATL &args) const
{
if (Trait::Rpc_direction<typename ATL::Head>::Type::IN)
ipc_client << args.get();
@ -58,7 +58,7 @@ namespace Genode {
template <typename T>
void Capability<RPC_INTERFACE>::
_unmarshal_result(Ipc_client &ipc_client, T &arg,
Meta::Overload_selector<Rpc_arg_out>)
Meta::Overload_selector<Rpc_arg_out>) const
{
ipc_client >> arg;
}
@ -68,7 +68,7 @@ namespace Genode {
template <typename T>
void Capability<RPC_INTERFACE>::
_unmarshal_result(Ipc_client &ipc_client, T &arg,
Meta::Overload_selector<Rpc_arg_inout>)
Meta::Overload_selector<Rpc_arg_inout>) const
{
_unmarshal_result(ipc_client, arg, Meta::Overload_selector<Rpc_arg_out>());
}
@ -77,7 +77,7 @@ namespace Genode {
template <typename RPC_INTERFACE>
template <typename ATL>
void Capability<RPC_INTERFACE>::
_unmarshal_results(Ipc_client &ipc_client, ATL &args)
_unmarshal_results(Ipc_client &ipc_client, ATL &args) const
{
/*
* Unmarshal current argument. The overload of
@ -95,7 +95,7 @@ namespace Genode {
template <typename RPC_INTERFACE>
template <typename IF>
void Capability<RPC_INTERFACE>::
_call(typename IF::Client_args &args, typename IF::Ret_type &ret)
_call(typename IF::Client_args &args, typename IF::Ret_type &ret) const
{
/**
* Message buffer for RPC message

View File

@ -458,20 +458,27 @@ namespace Genode {
* \param args function arguments
* \param func pointer-to-member function to invoke
*/
template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)());
template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)())
{ ret = (server.*func)(); }
template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)() const)
{ ret = (server.*func)(); }
template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &ret, SERVER &server, ARGS &args,
void (SERVER::*func)())
{ (server.*func)(); }
template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &ret, SERVER &server, ARGS &args,
void (SERVER::*func)() const)
{ (server.*func)(); }
/* 1 */
template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args,