genode/repos/base/include/base/rpc_server.h

518 lines
15 KiB
C
Raw Normal View History

2011-12-22 16:19:25 +01:00
/*
* \brief Server-side API of the RPC framework
* \author Norman Feske
* \date 2006-04-28
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
2011-12-22 16:19:25 +01:00
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
2011-12-22 16:19:25 +01:00
*/
#ifndef _INCLUDE__BASE__RPC_SERVER_H_
#define _INCLUDE__BASE__RPC_SERVER_H_
#include <base/rpc.h>
#include <base/thread.h>
#include <base/ipc.h>
#include <base/object_pool.h>
#include <base/lock.h>
#include <base/log.h>
2013-08-13 16:15:52 +02:00
#include <base/trace/events.h>
#include <pd_session/pd_session.h>
2011-12-22 16:19:25 +01:00
namespace Genode {
class Ipc_server;
template <typename, typename> class Rpc_dispatcher;
class Rpc_object_base;
template <typename, typename> struct Rpc_object;
class Rpc_entrypoint;
class Signal_receiver;
}
2011-12-22 16:19:25 +01:00
/**
* RPC dispatcher implementing the specified RPC interface
*
* \param RPC_INTERFACE class providing the RPC interface description
* \param SERVER class to invoke for the server-side RPC functions
*
* This class is the base class of each server-side RPC implementation. It
* contains the logic for dispatching incoming RPC requests and calls the
* server functions according to the RPC declarations in 'RPC_INTERFACE'.
*
* If using the default argument for 'SERVER', the 'RPC_INTERFACE' is expected
* to contain the abstract interface for all RPC functions. So virtual methods
* must be declared in 'RPC_INTERFACE'. In contrast, by explicitly specifying
* the 'SERVER' argument, the server-side dispatching performs direct
* calls to the respective methods of the 'SERVER' class and thereby
* omits virtual method calls.
*/
template <typename RPC_INTERFACE, typename SERVER = RPC_INTERFACE>
class Genode::Rpc_dispatcher : public RPC_INTERFACE
{
2011-12-22 16:19:25 +01:00
/**
* Shortcut for the type list of RPC functions provided by this server
* component
2011-12-22 16:19:25 +01:00
*/
typedef typename RPC_INTERFACE::Rpc_functions Rpc_functions;
2011-12-22 16:19:25 +01:00
protected:
2011-12-22 16:19:25 +01:00
template <typename ARG_LIST>
ARG_LIST _read_args(Ipc_unmarshaller &msg,
Meta::Overload_selector<ARG_LIST>)
{
typename Trait::Rpc_direction<typename ARG_LIST::Head>::Type direction;
typedef typename ARG_LIST::Stored_head Arg;
Arg arg = _read_arg<Arg>(msg, direction);
2011-12-22 16:19:25 +01:00
Meta::Overload_selector<typename ARG_LIST::Tail> tail_selector;
typename ARG_LIST::Tail subsequent_args = _read_args(msg,
tail_selector);
ARG_LIST args { arg, subsequent_args };
return args;
}
2011-12-22 16:19:25 +01:00
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Meta::Empty _read_args(Ipc_unmarshaller &,
Meta::Overload_selector<Meta::Empty>)
{
return Meta::Empty();
}
template <typename ARG>
ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_in)
{
return msg.extract(Meta::Overload_selector<ARG>());
}
template <typename ARG>
ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_inout)
{
return _read_arg<ARG>(msg, Rpc_arg_in());
}
template <typename ARG>
ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_out)
{
return ARG();
}
2011-12-22 16:19:25 +01:00
template <typename ARG_LIST>
void _write_results(Msgbuf_base &msg, ARG_LIST &args)
{
if (Trait::Rpc_direction<typename ARG_LIST::Head>::Type::OUT)
msg.insert(args._1);
2011-12-22 16:19:25 +01:00
_write_results(msg, args._2);
}
2011-12-22 16:19:25 +01:00
void _write_results(Msgbuf_base &, Meta::Empty) { }
2011-12-22 16:19:25 +01:00
template <typename RPC_FUNCTION, typename EXC_TL>
typename RPC_FUNCTION::Ret_type
_do_serve(typename RPC_FUNCTION::Server_args &args,
Meta::Overload_selector<RPC_FUNCTION, EXC_TL>)
{
enum { EXCEPTION_CODE = Rpc_exception_code::EXCEPTION_BASE
- Meta::Length<EXC_TL>::Value };
try {
typedef typename EXC_TL::Tail Exc_tail;
return _do_serve(args,
Meta::Overload_selector<RPC_FUNCTION, Exc_tail>());
} catch (typename EXC_TL::Head) {
/**
* By passing the exception code through an exception we ensure that
* a return value is only returned if it exists. This way, the return
* type does not have to be default-constructible.
*/
throw Rpc_exception_code(EXCEPTION_CODE);
}
}
2011-12-22 16:19:25 +01:00
template <typename RPC_FUNCTION>
typename RPC_FUNCTION::Ret_type
_do_serve(typename RPC_FUNCTION::Server_args &args,
Meta::Overload_selector<RPC_FUNCTION, Meta::Empty>)
{
typedef typename RPC_FUNCTION::Ret_type Ret_type;
SERVER *me = static_cast<SERVER *>(this);
return RPC_FUNCTION::template serve<SERVER, Ret_type>(*me, args);
}
2011-12-22 16:19:25 +01:00
template <typename RPC_FUNCTIONS_TO_CHECK>
Rpc_exception_code _do_dispatch(Rpc_opcode opcode,
Ipc_unmarshaller &in, Msgbuf_base &out,
Meta::Overload_selector<RPC_FUNCTIONS_TO_CHECK>)
{
using namespace Meta;
2011-12-22 16:19:25 +01:00
typedef typename RPC_FUNCTIONS_TO_CHECK::Head This_rpc_function;
2011-12-22 16:19:25 +01:00
if (opcode.value == Index_of<Rpc_functions, This_rpc_function>::Value) {
2011-12-22 16:19:25 +01:00
/* read arguments from incoming message */
typedef typename This_rpc_function::Server_args Server_args;
Meta::Overload_selector<Server_args> arg_selector;
Server_args args = _read_args(in, arg_selector);
2011-12-22 16:19:25 +01:00
{
Trace::Rpc_dispatch trace_event(This_rpc_function::name());
}
2011-12-22 16:19:25 +01:00
/*
* Dispatch call to matching RPC base class, using
* 'This_rpc_function' and the list of its exceptions to
* select the overload.
*/
typedef typename This_rpc_function::Ret_type Ret_type;
Rpc_exception_code exc(Rpc_exception_code::SUCCESS);
try {
typedef typename This_rpc_function::Exceptions Exceptions;
Overload_selector<This_rpc_function, Exceptions> overloader;
Ret_type ret = _do_serve(args, overloader);
_write_results(out, args);
out.insert(ret);
} catch (Rpc_exception_code thrown) {
/**
* Output arguments may be modified although an exception was thrown.
* However, a return value does not exist. So we do not insert one.
*/
_write_results(out, args);
exc = thrown;
}
2011-12-22 16:19:25 +01:00
{
Trace::Rpc_reply trace_event(This_rpc_function::name());
2011-12-22 16:19:25 +01:00
}
return exc;
2011-12-22 16:19:25 +01:00
}
typedef typename RPC_FUNCTIONS_TO_CHECK::Tail Tail;
return _do_dispatch(opcode, in, out, Overload_selector<Tail>());
}
Rpc_exception_code _do_dispatch(Rpc_opcode opcode,
Ipc_unmarshaller &, Msgbuf_base &,
Meta::Overload_selector<Meta::Empty>)
{
error("invalid opcode ", opcode.value);
return Rpc_exception_code(Rpc_exception_code::INVALID_OPCODE);
}
/**
* Handle corner case of having an RPC interface with no RPC functions
*/
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Rpc_exception_code _do_dispatch(Rpc_opcode,
Ipc_unmarshaller &, Msgbuf_base &,
Meta::Overload_selector<Meta::Type_list<> >)
{
return Rpc_exception_code(Rpc_exception_code::SUCCESS);
}
2011-12-22 16:19:25 +01:00
/**
* Protected constructor
*
* This class is only usable as base class.
*/
Rpc_dispatcher() { }
2011-12-22 16:19:25 +01:00
public:
2011-12-22 16:19:25 +01:00
Rpc_exception_code dispatch(Rpc_opcode opcode,
Ipc_unmarshaller &in, Msgbuf_base &out)
{
return _do_dispatch(opcode, in, out,
Meta::Overload_selector<Rpc_functions>());
}
};
2011-12-22 16:19:25 +01:00
class Genode::Rpc_object_base : public Object_pool<Rpc_object_base>::Entry
{
public:
2011-12-22 16:19:25 +01:00
virtual ~Rpc_object_base() { }
2011-12-22 16:19:25 +01:00
/**
* Interface to be implemented by a derived class
*
* \param op opcode of invoked method
* \param in incoming message with method arguments
* \param out outgoing message for storing method results
*/
virtual Rpc_exception_code
dispatch(Rpc_opcode op, Ipc_unmarshaller &in, Msgbuf_base &out) = 0;
};
2011-12-22 16:19:25 +01:00
/**
* Object that is accessible from remote protection domains
*
* A 'Rpc_object' is a locally implemented object that can be referenced
* from the outer world using a capability. The capability gets created
* when attaching a 'Rpc_object' to a 'Rpc_entrypoint'.
*/
template <typename RPC_INTERFACE, typename SERVER = RPC_INTERFACE>
struct Genode::Rpc_object : Rpc_object_base, Rpc_dispatcher<RPC_INTERFACE, SERVER>
{
struct Capability_guard;
Rpc_exception_code dispatch(Rpc_opcode opcode, Ipc_unmarshaller &in, Msgbuf_base &out) override
2011-12-22 16:19:25 +01:00
{
return Rpc_dispatcher<RPC_INTERFACE, SERVER>::dispatch(opcode, in, out);
}
2011-12-22 16:19:25 +01:00
Capability<RPC_INTERFACE> const cap() const
{
return reinterpret_cap_cast<RPC_INTERFACE>(Rpc_object_base::cap());
}
};
/**
* RPC entrypoint serving RPC objects
*
* The entrypoint's thread will initialize its capability but will not
* immediately enable the processing of requests. This way, the
* activation-using server can ensure that it gets initialized completely
* before the first capability invocations come in. Once the server is
* ready, it must enable the entrypoint explicitly by calling the
* 'activate()' method. The 'start_on_construction' argument is a
* shortcut for the common case where the server's capability is handed
* over to other parties _after_ the server is completely initialized.
*/
class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
{
/**
* This is only needed because in 'base-hw' we need the Thread
* pointer of the entrypoint to cancel its next signal blocking.
* Remove it as soon as signal dispatching in 'base-hw' doesn't need
* multiple threads anymore.
*/
friend class Signal_receiver;
private:
/**
* Prototype capability to derive capabilities for RPC objects
* from.
*/
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Untyped_capability _cap { };
enum { SND_BUF_SIZE = 1024, RCV_BUF_SIZE = 1024 };
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Msgbuf<SND_BUF_SIZE> _snd_buf { };
Msgbuf<RCV_BUF_SIZE> _rcv_buf { };
/**
* Hook to let low-level thread init code access private members
*
* This method is only used on NOVA.
*/
static void _activation_entry();
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
struct Exit : Genode::Interface
{
GENODE_RPC(Rpc_exit, void, _exit);
GENODE_RPC_INTERFACE(Rpc_exit);
};
struct Exit_handler : Rpc_object<Exit, Exit_handler>
2011-12-22 16:19:25 +01:00
{
int exit;
Exit_handler() : exit(false) { }
void _exit() { exit = true; }
};
protected:
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Native_capability _caller { };
Lock _cap_valid { }; /* thread startup synchronization */
Lock _delay_start { }; /* delay start of request dispatching */
Lock _delay_exit { }; /* delay destructor until server settled */
Pd_session &_pd_session; /* for creating capabilities */
Exit_handler _exit_handler { };
Capability<Exit> _exit_cap { };
/**
* Access to kernel-specific part of the PD session interface
*
* Some kernels like NOVA need a special interface for creating RPC
* object capabilities.
*/
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Capability<Pd_session::Native_pd> _native_pd_cap { };
/**
* Back end used to associate RPC object with the entry point
*
* \noapi
*/
Untyped_capability _manage(Rpc_object_base *obj);
/**
* Back end used to Dissolve RPC object from entry point
*
* \noapi
*/
void _dissolve(Rpc_object_base *obj);
/**
* Wait until the entrypoint activation is initialized
*
* \noapi
*/
void _block_until_cap_valid();
/**
* Allocate new RPC object capability
*
* Regular servers allocate capabilities from their protection domain
* via the component's environment. This method allows core to have a
* special implementation that does not rely on a PD session.
*
* The 'entry' argument is used only on NOVA. It is the server-side
* instruction pointer to be associated with the RPC object capability.
*/
Native_capability _alloc_rpc_cap(Pd_session &, Native_capability ep,
addr_t entry = 0);
/**
* Free RPC object capability
*/
void _free_rpc_cap(Pd_session &, Native_capability);
/**
* Thread interface
*
* \noapi
*/
void entry() override;
public:
/**
* Constructor
*
* \param pd_session 'Pd_session' for creating capabilities
* for the RPC objects managed by this entry
* point
* \param stack_size stack size of entrypoint thread
* \param name name of entrypoint thread
* \param location CPU affinity
*/
Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
char const *name, bool start_on_construction = true,
Affinity::Location location = Affinity::Location());
~Rpc_entrypoint();
/**
* Associate RPC object with the entry point
*/
template <typename RPC_INTERFACE, typename RPC_SERVER>
Capability<RPC_INTERFACE>
manage(Rpc_object<RPC_INTERFACE, RPC_SERVER> *obj)
{
return reinterpret_cap_cast<RPC_INTERFACE>(_manage(obj));
2011-12-22 16:19:25 +01:00
}
/**
* Dissolve RPC object from entry point
*/
template <typename RPC_INTERFACE, typename RPC_SERVER>
void dissolve(Rpc_object<RPC_INTERFACE, RPC_SERVER> *obj)
2011-12-22 16:19:25 +01:00
{
_dissolve(obj);
2011-12-22 16:19:25 +01:00
}
/**
* Activate entrypoint, start processing RPC requests
*/
void activate();
2011-12-22 16:19:25 +01:00
/**
* Request reply capability for current call
*
* \noapi
*
* Note: This is a temporary API method, which is going to be
* removed. Please do not use this method.
*
* Typically, a capability obtained via this method is used as
* argument of 'intermediate_reply'.
*/
Untyped_capability reply_dst() { return _caller; }
2011-12-22 16:19:25 +01:00
/**
* Prevent reply of current request
*
* \noapi
*
* Note: This is a temporary API method, which is going to be
* removed. Please do not use this method.
*
* This method can be used to keep the calling client blocked
* after the server has finished the processing of the client's
* request. At a later time, the server may chose to unblock the
* client via the 'intermedate_reply' method.
*/
void omit_reply() { _caller = Native_capability(); }
2011-12-22 16:19:25 +01:00
/**
* Send a reply out of the normal call-reply order
*
* \noapi
*
* In combination with the 'reply_dst' accessor method, this method
* allows for the dispatching of client requests out of order. The only
* designated user of this method is core's PD service. The
* 'Pd_session::submit' RPC function uses it to send a reply to a
* caller of the 'Signal_source::wait_for_signal' RPC function before
* returning from the 'submit' call.
*/
void reply_signal_info(Untyped_capability reply_cap,
unsigned long imprint, unsigned long cnt);
/**
* Return true if the caller corresponds to the entrypoint called
*
* \noapi
*
* This method is solely needed on Linux.
*/
bool is_myself() const;
/**
* Required outside of core. E.g. launchpad needs it to forcefully kill
* a client which blocks on a session opening request where the service
* is not up yet.
*/
void cancel_blocking() { Thread::cancel_blocking(); }
};
2011-12-22 16:19:25 +01:00
template <typename IF, typename SERVER>
struct Genode::Rpc_object<IF, SERVER>::Capability_guard
{
Rpc_entrypoint &_ep;
Rpc_object &_obj;
Capability_guard(Rpc_entrypoint &ep, Rpc_object &obj)
: _ep(ep), _obj(obj) { _ep.manage(&_obj); }
~Capability_guard() { _ep.dissolve(&_obj); }
};
2011-12-22 16:19:25 +01:00
#endif /* _INCLUDE__BASE__RPC_SERVER_H_ */