os: manage/dissolve Signal_rpc_member in class

Instead of, passing responsibility to manage and dissolve Signal_rpc_member
objects at a corresponding entrypoint to the user, hand over entrypoint's
reference to the constructor, and do it in the constructor resp. destructor
of the class.

Fixes #1022
This commit is contained in:
Stefan Kalkowski 2014-01-10 11:42:31 +01:00 committed by Norman Feske
parent bf57a5d79c
commit 65291902e0
4 changed files with 29 additions and 25 deletions

View File

@ -21,7 +21,7 @@ namespace Genode {
class Signal_rpc_dispatcher_base;
template <typename> class Signal_rpc_functor;
template <typename> class Signal_rpc_member;
template <typename, typename> class Signal_rpc_member;
template <typename FUNCTOR>
Signal_rpc_functor<FUNCTOR> signal_rpc_functor(FUNCTOR &);
@ -148,6 +148,11 @@ struct Genode::Signal_rpc_functor : Genode::Signal_rpc_dispatcher_base
};
namespace Server{
class Entrypoint;
}
/**
* Signal dispatcher for directing signals via RPC to member function
*
@ -159,21 +164,28 @@ struct Genode::Signal_rpc_functor : Genode::Signal_rpc_dispatcher_base
* 'Signal_dispatcher_base::dispatch'.
*
* \param T type of signal-handling class
* \param EP type of entrypoint handling signal RPC
*/
template <typename T>
struct Genode::Signal_rpc_member : Genode::Signal_rpc_dispatcher_base
template <typename T, typename EP = Server::Entrypoint>
struct Genode::Signal_rpc_member : Genode::Signal_rpc_dispatcher_base,
Genode::Signal_context_capability
{
T &obj;
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(T &obj, void (T::*member)(unsigned))
: obj(obj), member(member) { }
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

View File

@ -160,16 +160,14 @@ class File_system::Session_component : public Session_rpc_object
_md_alloc(md_alloc),
_root(*new (&_md_alloc) Directory(_md_alloc, root_dir, false)),
_writable(writable),
_process_packet_dispatcher(*this, &Session_component::_process_packets)
_process_packet_dispatcher(ep, *this, &Session_component::_process_packets)
{
/*
* Register '_process_packets' dispatch function as signal
* handler for packet-avail and ready-to-ack signals.
*/
Signal_context_capability sigh(_ep.manage(_process_packet_dispatcher));
_tx.sigh_packet_avail(sigh);
_tx.sigh_ready_to_ack(sigh);
_tx.sigh_packet_avail(_process_packet_dispatcher);
_tx.sigh_ready_to_ack(_process_packet_dispatcher);
}
/**
@ -177,7 +175,6 @@ class File_system::Session_component : public Session_rpc_object
*/
~Session_component()
{
_ep.dissolve(_process_packet_dispatcher);
Dataspace_capability ds = tx_sink()->dataspace();
env()->ram_session()->free(static_cap_cast<Ram_dataspace>(ds));
destroy(&_md_alloc, &_root);

View File

@ -813,16 +813,14 @@ struct Nitpicker::Main
*/
void handle_config(unsigned);
Signal_rpc_member<Main> config_dispatcher = { *this, &Main::handle_config };
Signal_context_capability config_sigh = ep.manage(config_dispatcher);
Signal_rpc_member<Main> config_dispatcher = { ep, *this, &Main::handle_config};
/**
* Signal handler invoked on the reception of user input
*/
void handle_input(unsigned);
Signal_rpc_member<Main> input_dispatcher = { *this, &Main::handle_input };
Signal_rpc_member<Main> input_dispatcher = { ep, *this, &Main::handle_input };
/*
* Dispatch input on periodic timer signals every 10 milliseconds
@ -838,10 +836,10 @@ struct Nitpicker::Main
user_state.stack(menubar);
user_state.stack(background);
config()->sigh(config_sigh);
Signal_transmitter(config_sigh).submit();
config()->sigh(config_dispatcher);
Signal_transmitter(config_dispatcher).submit();
timer.sigh(ep.manage(input_dispatcher));
timer.sigh(input_dispatcher);
timer.trigger_periodic(10*1000);
env()->parent()->announce(ep.manage(np_root));

View File

@ -154,16 +154,14 @@ namespace File_system {
_ep(ep),
_root(root),
_writable(writable),
_process_packet_dispatcher(*this, &Session_component::_process_packets)
_process_packet_dispatcher(ep, *this, &Session_component::_process_packets)
{
/*
* Register '_process_packets' dispatch function as signal
* handler for packet-avail and ready-to-ack signals.
*/
Signal_context_capability sigh(_ep.manage(_process_packet_dispatcher));
_tx.sigh_packet_avail(sigh);
_tx.sigh_ready_to_ack(sigh);
_tx.sigh_packet_avail(_process_packet_dispatcher);
_tx.sigh_ready_to_ack(_process_packet_dispatcher);
}
/**
@ -171,7 +169,6 @@ namespace File_system {
*/
~Session_component()
{
_ep.dissolve(_process_packet_dispatcher);
Dataspace_capability ds = tx_sink()->dataspace();
env()->ram_session()->free(static_cap_cast<Ram_dataspace>(ds));
}