core: fix deadlock in signal delivery

Acquire Signal_context objects locks via Object_pool::apply() in the
context of the entrpyoint thread, instead in the context of the calling
thread.

Fixes #2485
This commit is contained in:
Alexander Boettcher 2017-08-16 14:14:07 +02:00 committed by Christian Helmuth
parent 31d11ec990
commit b1a27b417b
1 changed files with 10 additions and 21 deletions

View File

@ -30,13 +30,7 @@ namespace {
struct Signal_delivery_proxy
{
/*
* Wrap pointer into struct to transmit it (core-locally) as plain-old
* data.
*/
struct Context_ptr { Signal_context_component *ptr; };
GENODE_RPC(Rpc_deliver, void, _deliver_from_ep, Context_ptr, unsigned);
GENODE_RPC(Rpc_deliver, void, _deliver_from_ep, Signal_context_capability, unsigned);
GENODE_RPC_INTERFACE(Rpc_deliver);
};
@ -63,10 +57,14 @@ namespace {
* can produce legitimate IPC reply messages to 'Signal_source'
* clients.
*/
void _deliver_from_ep(Context_ptr context_ptr, unsigned cnt)
void _deliver_from_ep(Signal_context_capability cap, unsigned cnt)
{
Signal_context_component *context = context_ptr.ptr;
context->source()->submit(context, cnt);
_ep.apply(cap, [&] (Signal_context_component *context) {
if (context)
context->source()->submit(context, cnt);
else
warning("invalid signal-context capability");
});
}
/**
@ -77,17 +75,8 @@ namespace {
*
* Called from threads other than 'ep'.
*/
void submit(Signal_context_capability cap, unsigned cnt)
{
_ep.apply(cap, [&] (Signal_context_component *context) {
if (context) {
_proxy_cap.call<Rpc_deliver>(Context_ptr{context}, cnt);
} else {
warning("invalid signal-context capability");
}
});
}
void submit(Signal_context_capability cap, unsigned cnt) {
_proxy_cap.call<Rpc_deliver>(cap, cnt); }
};
}