parent
5d969cffaf
commit
09e04d6378
|
@ -70,8 +70,10 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
|
||||||
|
|
||||||
|
|
||||||
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
||||||
: Signal_source_rpc_object(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
|
:
|
||||||
_entrypoint(ep)
|
Signal_source_rpc_object(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
|
||||||
|
_entrypoint(ep), _finalizer(*this),
|
||||||
|
_finalizer_cap(_entrypoint->manage(&_finalizer))
|
||||||
{
|
{
|
||||||
using namespace Fiasco;
|
using namespace Fiasco;
|
||||||
|
|
||||||
|
@ -80,3 +82,20 @@ Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
||||||
if (l4_error(res))
|
if (l4_error(res))
|
||||||
PERR("Allocation of irq object failed!");
|
PERR("Allocation of irq object failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Signal_source_component::~Signal_source_component()
|
||||||
|
{
|
||||||
|
_finalizer_cap.call<Finalizer::Rpc_exit>();
|
||||||
|
_entrypoint->dissolve(&_finalizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Signal_source_component::Finalizer_component::exit()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* On Fiasco.OC, the signal-source client does not use a blocking call
|
||||||
|
* to wait for signals. Hence, we do not need to take care of
|
||||||
|
* releasing the reply capability of such a call.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
|
@ -69,7 +69,9 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
|
||||||
|
|
||||||
|
|
||||||
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
||||||
: _entrypoint(ep)
|
:
|
||||||
|
_entrypoint(ep), _finalizer(*this),
|
||||||
|
_finalizer_cap(_entrypoint->manage(&_finalizer))
|
||||||
{
|
{
|
||||||
/* initialized blocking semaphore */
|
/* initialized blocking semaphore */
|
||||||
addr_t sem_sel = cap_selector_allocator()->alloc();
|
addr_t sem_sel = cap_selector_allocator()->alloc();
|
||||||
|
@ -79,3 +81,20 @@ Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
||||||
|
|
||||||
_blocking_semaphore = Native_capability(sem_sel);
|
_blocking_semaphore = Native_capability(sem_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Signal_source_component::~Signal_source_component()
|
||||||
|
{
|
||||||
|
_finalizer_cap.call<Finalizer::Rpc_exit>();
|
||||||
|
_entrypoint->dissolve(&_finalizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Signal_source_component::Finalizer_component::exit()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* On NOVA, the signal-source client does not use a blocking call
|
||||||
|
* to wait for signals. Hence, we do not need to take care of
|
||||||
|
* releasing the reply capability of such a call.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
|
@ -71,11 +71,44 @@ namespace Genode {
|
||||||
|
|
||||||
class Signal_source_component : public Signal_source_rpc_object
|
class Signal_source_component : public Signal_source_rpc_object
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Helper for clean destruction of signal-source component
|
||||||
|
*
|
||||||
|
* Normally, reply capabilities are implicitly destroyed when answering
|
||||||
|
* an RPC call. But when destructing a signal session while a signal-
|
||||||
|
* source client is blocking on a 'wait_for_signal' call, this
|
||||||
|
* blocking call will never return via the normal control flow
|
||||||
|
* (signal submission). In this case, the reply capability would
|
||||||
|
* outlive the signal session. To avoid the leakage of such reply
|
||||||
|
* capabilities, we let the signal-session destructor perform a
|
||||||
|
* core-local RPC call to the so-called 'Finalizer' object, which has
|
||||||
|
* the sole purpose of replying to the last outstanding
|
||||||
|
* 'wait_for_signal' call and thereby releasing the corresponding
|
||||||
|
* reply capability.
|
||||||
|
*/
|
||||||
|
struct Finalizer
|
||||||
|
{
|
||||||
|
GENODE_RPC(Rpc_exit, void, exit);
|
||||||
|
GENODE_RPC_INTERFACE(Rpc_exit);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Finalizer_component : Rpc_object<Finalizer, Finalizer_component>
|
||||||
|
{
|
||||||
|
Signal_source_component &source;
|
||||||
|
|
||||||
|
Finalizer_component(Signal_source_component &source)
|
||||||
|
: source(source) { }
|
||||||
|
|
||||||
|
void exit();
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Signal_queue _signal_queue;
|
Signal_queue _signal_queue;
|
||||||
Rpc_entrypoint *_entrypoint;
|
Rpc_entrypoint *_entrypoint;
|
||||||
Native_capability _reply_cap;
|
Native_capability _reply_cap;
|
||||||
|
Finalizer_component _finalizer;
|
||||||
|
Capability<Finalizer> _finalizer_cap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -84,6 +117,8 @@ namespace Genode {
|
||||||
*/
|
*/
|
||||||
Signal_source_component(Rpc_entrypoint *rpc_entrypoint);
|
Signal_source_component(Rpc_entrypoint *rpc_entrypoint);
|
||||||
|
|
||||||
|
~Signal_source_component();
|
||||||
|
|
||||||
void release(Signal_context_component *context);
|
void release(Signal_context_component *context);
|
||||||
|
|
||||||
void submit(Signal_context_component *context,
|
void submit(Signal_context_component *context,
|
||||||
|
|
|
@ -46,7 +46,6 @@ Signal_session_component::~Signal_session_component()
|
||||||
/* free all signal contexts */
|
/* free all signal contexts */
|
||||||
while (Signal_context_component *r = _contexts_slab.first_object())
|
while (Signal_context_component *r = _contexts_slab.first_object())
|
||||||
free_context(r->cap());
|
free_context(r->cap());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -90,5 +90,24 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
|
||||||
|
|
||||||
|
|
||||||
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
|
||||||
: _entrypoint(ep) { }
|
:
|
||||||
|
_entrypoint(ep), _finalizer(*this),
|
||||||
|
_finalizer_cap(_entrypoint->manage(&_finalizer))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
Signal_source_component::~Signal_source_component()
|
||||||
|
{
|
||||||
|
_finalizer_cap.call<Finalizer::Rpc_exit>();
|
||||||
|
_entrypoint->dissolve(&_finalizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Signal_source_component::Finalizer_component::exit()
|
||||||
|
{
|
||||||
|
if (!source._reply_cap.valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
source._entrypoint->explicit_reply(source._reply_cap, 0);
|
||||||
|
source._reply_cap = Untyped_capability();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue