From 42397cb51260066aa14c2c744d41a75ccbedb190 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Wed, 18 Jun 2014 15:04:30 +0200 Subject: [PATCH] os: avoid deadlock in packet stream (fix #1186) Respectively resend a packet-stream-not-empty signal when a new signal handler gets registered. --- repos/base/include/base/signal.h | 7 +++++++ repos/base/src/base/signal/common.cc | 2 ++ repos/os/include/os/packet_stream.h | 16 ++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/repos/base/include/base/signal.h b/repos/base/include/base/signal.h index 55ce6f473..acd3e1cd9 100644 --- a/repos/base/include/base/signal.h +++ b/repos/base/include/base/signal.h @@ -132,6 +132,13 @@ namespace Genode { */ void context(Signal_context_capability context); + + /** + * Return signal context + */ + Signal_context_capability context(); + + /** * Trigger signal submission to context * diff --git a/repos/base/src/base/signal/common.cc b/repos/base/src/base/signal/common.cc index 02d9abf42..7de4ebe65 100644 --- a/repos/base/src/base/signal/common.cc +++ b/repos/base/src/base/signal/common.cc @@ -78,6 +78,8 @@ Signal_transmitter::Signal_transmitter(Signal_context_capability context) void Signal_transmitter::context(Signal_context_capability context) { _context = context; } +Signal_context_capability Signal_transmitter::context() { return _context; } + /********************* ** Signal_receiver ** diff --git a/repos/os/include/os/packet_stream.h b/repos/os/include/os/packet_stream.h index 03c57c880..61dd7b51c 100644 --- a/repos/os/include/os/packet_stream.h +++ b/repos/os/include/os/packet_stream.h @@ -260,6 +260,14 @@ class Packet_descriptor_transmitter void register_rx_ready_cap(Genode::Signal_context_capability cap) { _rx_ready.context(cap); + + /* + * if a packet was already put into the queue + * before a signal handler was registered, + * a signal has to be send again + */ + if (!_tx_queue->empty()) + _rx_ready.submit(); } bool ready_for_tx() @@ -341,6 +349,14 @@ class Packet_descriptor_receiver void register_tx_ready_cap(Genode::Signal_context_capability cap) { _tx_ready.context(cap); + + /* + * if a packet was already put into the queue + * before a signal handler was registered, + * a signal has to be send again + */ + if (!_rx_queue->empty()) + _tx_ready.submit(); } bool ready_for_rx()