mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-12 07:52:44 +00:00
ca971bbfd8
This patch changes the top-level directory layout as a preparatory step for improving the tools for managing 3rd-party source codes. The rationale is described in the issue referenced below. Issue #1082
186 lines
4.7 KiB
C++
186 lines
4.7 KiB
C++
/*
|
|
* \brief Utility for dispatching signals via an RPC entrypoint **
|
|
* \author Norman Feske
|
|
* \date 2013-09-07
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2013 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#ifndef _INCLUDE__OS__SIGNAL_RPC_DISPATCHER_H_
|
|
#define _INCLUDE__OS__SIGNAL_RPC_DISPATCHER_H_
|
|
|
|
#include <base/rpc_server.h>
|
|
#include <base/signal.h>
|
|
|
|
namespace Genode {
|
|
|
|
class Signal_rpc_dispatcher_base;
|
|
template <typename> class Signal_rpc_functor;
|
|
template <typename, typename> class Signal_rpc_member;
|
|
|
|
template <typename FUNCTOR>
|
|
Signal_rpc_functor<FUNCTOR> signal_rpc_functor(FUNCTOR &);
|
|
}
|
|
|
|
|
|
struct Genode::Signal_rpc_dispatcher_base : Genode::Signal_dispatcher_base
|
|
{
|
|
private:
|
|
|
|
struct Proxy
|
|
{
|
|
GENODE_RPC(Rpc_handle_signal, void, handle_signal, unsigned);
|
|
GENODE_RPC_INTERFACE(Rpc_handle_signal);
|
|
};
|
|
|
|
struct Proxy_component : Genode::Rpc_object<Proxy, Proxy_component>
|
|
{
|
|
Genode::Signal_rpc_dispatcher_base &_dispatcher;
|
|
|
|
Proxy_component(Signal_rpc_dispatcher_base &dispatcher)
|
|
: _dispatcher(dispatcher) { }
|
|
|
|
void handle_signal(unsigned num)
|
|
{
|
|
_dispatcher.dispatch_at_entrypoint(num);
|
|
}
|
|
};
|
|
|
|
Proxy_component _proxy;
|
|
Capability<Proxy> _proxy_cap;
|
|
|
|
protected:
|
|
|
|
Signal_rpc_dispatcher_base() : _proxy(*this) { }
|
|
|
|
Capability<Proxy> proxy_cap() { return _proxy_cap; }
|
|
|
|
public:
|
|
|
|
/**
|
|
* Associate signal dispatcher with entrypoint
|
|
*/
|
|
Signal_context_capability manage(Signal_receiver &sig_rec, Rpc_entrypoint &ep)
|
|
{
|
|
_proxy_cap = ep.manage(&_proxy);
|
|
return sig_rec.manage(this);
|
|
}
|
|
|
|
/**
|
|
* Disassociate signal dispatcher from entrypoint
|
|
*/
|
|
void dissolve(Signal_receiver &sig_rec, Rpc_entrypoint &ep)
|
|
{
|
|
ep.dissolve(&_proxy);
|
|
_proxy_cap = Capability<Proxy>();
|
|
sig_rec.dissolve(this);
|
|
}
|
|
|
|
public:
|
|
|
|
/**
|
|
* Interface of Signal_dispatcher_base
|
|
*/
|
|
void dispatch(unsigned num) {
|
|
proxy_cap().call<Proxy::Rpc_handle_signal>(num); }
|
|
|
|
/**
|
|
* To be implemented by the derived class
|
|
*/
|
|
virtual void dispatch_at_entrypoint(unsigned num) = 0;
|
|
};
|
|
|
|
|
|
/**
|
|
* Signal dispatcher that executes the signal handling code in the context
|
|
* of an RPC entrypoint
|
|
*
|
|
* The 'Signal_rpc_dispatcher' provides an easy way for a server to serialize
|
|
* the handling of signals with incoming RPC requests. Incoming signals are
|
|
* delegated to the RPC entrypoint via a local RPC call. The signal handling
|
|
* code is then executed in the context of the RPC entrypoint.
|
|
*/
|
|
template <typename FUNCTOR>
|
|
struct Genode::Signal_rpc_functor : Genode::Signal_rpc_dispatcher_base
|
|
{
|
|
FUNCTOR &functor;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* \param func functor taking containing the signal-handling code
|
|
*
|
|
* The functor 'func' has the signature 'void func(unsigned num)'
|
|
* whereas 'num' is the number of signals received at once.
|
|
*/
|
|
Signal_rpc_functor(FUNCTOR &functor) : functor(functor) { }
|
|
|
|
/**
|
|
* Interface of Signal_rpc_dispatcher_base
|
|
*/
|
|
void dispatch_at_entrypoint(unsigned num) { functor(num); }
|
|
};
|
|
|
|
|
|
namespace Server{
|
|
class Entrypoint;
|
|
}
|
|
|
|
|
|
/**
|
|
* Signal dispatcher for directing signals via RPC to member function
|
|
*
|
|
* This utility associates member functions with signals. It is intended to
|
|
* be used as a member variable of the class that handles incoming signals
|
|
* of a certain type. The constructor takes a pointer-to-member to the
|
|
* signal handling function as argument. If a signal is received at the
|
|
* common signal reception code, this function will be invoked by calling
|
|
* 'Signal_dispatcher_base::dispatch'.
|
|
*
|
|
* \param T type of signal-handling class
|
|
* \param EP type of entrypoint handling signal RPC
|
|
*/
|
|
template <typename T, typename EP = Server::Entrypoint>
|
|
struct Genode::Signal_rpc_member : Genode::Signal_rpc_dispatcher_base,
|
|
Genode::Signal_context_capability
|
|
{
|
|
EP &ep;
|
|
T &obj;
|
|
void (T::*member) (unsigned);
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* \param ep entrypoint managing this signal RPC
|
|
* \param obj,member object and member function to call when
|
|
* the signal occurs
|
|
*/
|
|
Signal_rpc_member(EP &ep, T &obj, void (T::*member)(unsigned))
|
|
: Signal_context_capability(ep.manage(*this)),
|
|
ep(ep), obj(obj), member(member) { }
|
|
|
|
~Signal_rpc_member() { ep.dissolve(*this); }
|
|
|
|
/**
|
|
* Interface of Signal_rpc_dispatcher_base
|
|
*/
|
|
void dispatch_at_entrypoint(unsigned num) { (obj.*member)(num); }
|
|
};
|
|
|
|
|
|
/**
|
|
* Convenience utility for creating 'Signal_rpc_dispatcher' objects
|
|
*/
|
|
template <typename FUNCTOR>
|
|
Genode::Signal_rpc_functor<FUNCTOR> Genode::signal_rpc_functor(FUNCTOR &func)
|
|
{
|
|
return Signal_rpc_functor<FUNCTOR>(func);
|
|
}
|
|
|
|
#endif /* _INCLUDE__OS__SIGNAL_RPC_DISPATCHER_H_ */
|