From 210eb985981b878a8b93caba52dc94587ef25734 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 25 Jan 2012 22:33:24 +0100 Subject: [PATCH] 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. --- base/include/base/capability.h | 40 ++++++++++++++++++---------------- base/include/base/rpc_client.h | 10 ++++----- base/include/util/meta.h | 13 ++++++++--- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/base/include/base/capability.h b/base/include/base/capability.h index b3d9e3703..9d7a117eb 100644 --- a/base/include/base/capability.h +++ b/base/include/base/capability.h @@ -48,32 +48,32 @@ namespace Genode { * Insert RPC arguments into the message buffer */ template - 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 void _unmarshal_result(Ipc_client &ipc_client, T &arg, - Meta::Overload_selector); + Meta::Overload_selector) const; template void _unmarshal_result(Ipc_client &ipc_client, T &arg, - Meta::Overload_selector); + Meta::Overload_selector) const; template void _unmarshal_result(Ipc_client &, T &arg, - Meta::Overload_selector) { } + Meta::Overload_selector) const { } /** * Read RPC results from the message buffer */ template - 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 void _check_for_exceptions(Rpc_exception_code const exc_code, - Meta::Overload_selector) + Meta::Overload_selector) const { enum { EXCEPTION_CODE = RPC_EXCEPTION_BASE - Meta::Length::Value }; @@ -97,13 +97,15 @@ namespace Genode { } void _check_for_exceptions(Rpc_exception_code const, - Meta::Overload_selector) { } + Meta::Overload_selector) const + { } /** * Perform RPC call, arguments passed a as nested 'Ref_tuple' object */ template - 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 Untyped_capability - _check_compatibility(Capability const &cap) + _check_compatibility(Capability const &cap) const { FROM_RPC_INTERFACE *from = 0; RPC_INTERFACE *to = from; @@ -158,7 +160,7 @@ namespace Genode { template typename Trait::Call_return::Type - call() + call() const { Meta::Empty e; typename Trait::Call_return::Type ret; @@ -168,7 +170,7 @@ namespace Genode { template typename Trait::Call_return::Type - call(typename Arg::Type v1) + call(typename Arg::Type v1) const { Meta::Empty e; typename IF::Client_args args(v1, e); @@ -179,7 +181,7 @@ namespace Genode { template typename Trait::Call_return::Type - call(typename Arg::Type v1, typename Arg::Type v2) + call(typename Arg::Type v1, typename Arg::Type v2) const { Meta::Empty e; typename IF::Client_args args(v1, v2, e); @@ -191,7 +193,7 @@ namespace Genode { template typename Trait::Call_return::Type call(typename Arg::Type v1, typename Arg::Type v2, - typename Arg::Type v3) + typename Arg::Type v3) const { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, e); @@ -203,7 +205,7 @@ namespace Genode { template typename Trait::Call_return::Type call(typename Arg::Type v1, typename Arg::Type v2, - typename Arg::Type v3, typename Arg::Type v4) + typename Arg::Type v3, typename Arg::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::Type call(typename Arg::Type v1, typename Arg::Type v2, typename Arg::Type v3, typename Arg::Type v4, - typename Arg::Type v5) + typename Arg::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::Type call(typename Arg::Type v1, typename Arg::Type v2, typename Arg::Type v3, typename Arg::Type v4, - typename Arg::Type v5, typename Arg::Type v6) + typename Arg::Type v5, typename Arg::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::Type v1, typename Arg::Type v2, typename Arg::Type v3, typename Arg::Type v4, typename Arg::Type v5, typename Arg::Type v6, - typename Arg::Type v7) + typename Arg::Type v7) const { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, v4, v5, v6, v7, e); diff --git a/base/include/base/rpc_client.h b/base/include/base/rpc_client.h index 9133e5bbd..08e848814 100644 --- a/base/include/base/rpc_client.h +++ b/base/include/base/rpc_client.h @@ -45,7 +45,7 @@ namespace Genode { template template void Capability:: - _marshal_args(Ipc_client &ipc_client, ATL &args) + _marshal_args(Ipc_client &ipc_client, ATL &args) const { if (Trait::Rpc_direction::Type::IN) ipc_client << args.get(); @@ -58,7 +58,7 @@ namespace Genode { template void Capability:: _unmarshal_result(Ipc_client &ipc_client, T &arg, - Meta::Overload_selector) + Meta::Overload_selector) const { ipc_client >> arg; } @@ -68,7 +68,7 @@ namespace Genode { template void Capability:: _unmarshal_result(Ipc_client &ipc_client, T &arg, - Meta::Overload_selector) + Meta::Overload_selector) const { _unmarshal_result(ipc_client, arg, Meta::Overload_selector()); } @@ -77,7 +77,7 @@ namespace Genode { template template void Capability:: - _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 template void Capability:: - _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 diff --git a/base/include/util/meta.h b/base/include/util/meta.h index b8eb7cd65..1b54de511 100644 --- a/base/include/util/meta.h +++ b/base/include/util/meta.h @@ -458,20 +458,27 @@ namespace Genode { * \param args function arguments * \param func pointer-to-member function to invoke */ - template - static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, - RET_TYPE (SERVER::*func)()); template static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, RET_TYPE (SERVER::*func)()) { ret = (server.*func)(); } + template + static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, + RET_TYPE (SERVER::*func)() const) + { ret = (server.*func)(); } + template static inline void call_member(Meta::Empty &ret, SERVER &server, ARGS &args, void (SERVER::*func)()) { (server.*func)(); } + template + static inline void call_member(Meta::Empty &ret, SERVER &server, ARGS &args, + void (SERVER::*func)() const) + { (server.*func)(); } + /* 1 */ template static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args,