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

View File

@ -30,13 +30,7 @@ namespace {
struct Signal_delivery_proxy struct Signal_delivery_proxy
{ {
/* GENODE_RPC(Rpc_deliver, void, _deliver_from_ep, Signal_context_capability, unsigned);
* 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_INTERFACE(Rpc_deliver); GENODE_RPC_INTERFACE(Rpc_deliver);
}; };
@ -63,10 +57,14 @@ namespace {
* can produce legitimate IPC reply messages to 'Signal_source' * can produce legitimate IPC reply messages to 'Signal_source'
* clients. * 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; _ep.apply(cap, [&] (Signal_context_component *context) {
context->source()->submit(context, cnt); if (context)
context->source()->submit(context, cnt);
else
warning("invalid signal-context capability");
});
} }
/** /**
@ -77,17 +75,8 @@ namespace {
* *
* Called from threads other than 'ep'. * Called from threads other than 'ep'.
*/ */
void submit(Signal_context_capability cap, unsigned cnt) void submit(Signal_context_capability cap, unsigned cnt) {
{ _proxy_cap.call<Rpc_deliver>(cap, 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");
}
});
}
}; };
} }