diff --git a/repos/base/src/core/include/signal_broker.h b/repos/base/src/core/include/signal_broker.h index 8678828c71..4c1971af8b 100644 --- a/repos/base/src/core/include/signal_broker.h +++ b/repos/base/src/core/include/signal_broker.h @@ -91,8 +91,15 @@ class Genode::Signal_broker _context_ep.dissolve(context); }); - if (context) - destroy(&_contexts_slab, context); + if (!context) + return; + + /* release solely in context of context_ep thread */ + if (context->enqueued() && context->source() && + !_context_ep.is_myself()) + _delivery_proxy.release(context); + + destroy(&_contexts_slab, context); } void submit(Signal_context_capability const cap, unsigned const cnt) diff --git a/repos/base/src/core/include/signal_delivery_proxy.h b/repos/base/src/core/include/signal_delivery_proxy.h index 20f226f9d4..055b66f7fe 100644 --- a/repos/base/src/core/include/signal_delivery_proxy.h +++ b/repos/base/src/core/include/signal_delivery_proxy.h @@ -19,7 +19,8 @@ namespace Genode { struct Signal_delivery_proxy { GENODE_RPC(Rpc_deliver, void, _deliver_from_ep, Signal_context_capability, unsigned); - GENODE_RPC_INTERFACE(Rpc_deliver); + GENODE_RPC(Rpc_release, void, _release_from_ep, Genode::addr_t); + GENODE_RPC_INTERFACE(Rpc_deliver, Rpc_release); }; struct Signal_delivery_proxy_component @@ -64,6 +65,13 @@ namespace Genode { }); } + void _release_from_ep(addr_t const context_addr) + { + Signal_context_component * context = reinterpret_cast(context_addr); + if (context && context->source()) + context->source()->release(context); + } + /** * Deliver signal via the proxy mechanism * @@ -74,6 +82,17 @@ namespace Genode { */ void submit(Signal_context_capability cap, unsigned cnt) { _proxy_cap.call(cap, cnt); } + + /** + * Deliver signal via the proxy mechanism + * + * Since this method perform an RPC call to the 'ep' specified at the + * constructor, is must never be called from this ep. + * + * Called from threads other than 'ep'. + */ + void release(Signal_context_component * context) { + _proxy_cap.call(reinterpret_cast(context)); } }; }