From 53d471aa22aa18c704ce2ee1c2085ba65cb8bb1b Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 30 Sep 2014 15:40:16 +0200 Subject: [PATCH] nova: handle race during signal setup phase Fixes #1266 --- .../signal_session/source_rpc_object.h | 55 ++++++++++++++----- .../src/core/signal_source_component.cc | 3 +- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/repos/base-nova/include/signal_session/source_rpc_object.h b/repos/base-nova/include/signal_session/source_rpc_object.h index 8ed857f5f1..4a05cf5f42 100644 --- a/repos/base-nova/include/signal_session/source_rpc_object.h +++ b/repos/base-nova/include/signal_session/source_rpc_object.h @@ -22,23 +22,52 @@ #include #include -namespace Genode { +namespace Genode { struct Signal_source_rpc_object; } - struct Signal_source_rpc_object : Rpc_object - { - protected: +struct Genode::Signal_source_rpc_object : Rpc_object +{ + private: - Native_capability _blocking_semaphore; + Native_capability _blocking_semaphore; + bool _missed_wakeup; - public: + protected: - void _register_semaphore(Native_capability const &cap) - { - if (_blocking_semaphore.valid()) - PWRN("overwritting blocking signal semaphore !!!"); - _blocking_semaphore = cap; + void _wakeup_client() + { + if (!_blocking_semaphore.valid()) { + _missed_wakeup = true; + return; } - }; -} + + if (_missed_wakeup) + _missed_wakeup = false; + + /* wake up client */ + uint8_t res = Nova::sm_ctrl(_blocking_semaphore.local_name(), + Nova::SEMAPHORE_UP); + if (res != Nova::NOVA_OK) { + PWRN("%s - signal delivery failed - error %x", + __func__, res); + _missed_wakeup = true; + } + } + + public: + + void _register_semaphore(Native_capability const &cap) + { + if (_blocking_semaphore.valid()) + PWRN("overwritting blocking signal semaphore !!!"); + + _blocking_semaphore = cap; + + if (_missed_wakeup) + _wakeup_client(); + } + + Signal_source_rpc_object() : _missed_wakeup(false) {} +}; #endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_ */ diff --git a/repos/base-nova/src/core/signal_source_component.cc b/repos/base-nova/src/core/signal_source_component.cc index cb412a53f9..9a502f536e 100644 --- a/repos/base-nova/src/core/signal_source_component.cc +++ b/repos/base-nova/src/core/signal_source_component.cc @@ -46,8 +46,7 @@ void Signal_source_component::submit(Signal_context_component *context, if (!context->is_enqueued()) { _signal_queue.enqueue(context); - /* wake up client */ - Nova::sm_ctrl(_blocking_semaphore.local_name(), Nova::SEMAPHORE_UP); + _wakeup_client(); } }