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();
}
}