mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
base: don't throw exceptions in 'Signal_receiver::pending_signal()'
Issue #3922
This commit is contained in:
parent
f754e2a7d7
commit
50e0f3b977
@ -158,7 +158,7 @@ Signal Signal_receiver::pending_signal()
|
||||
Signal::Data result;
|
||||
_contexts.for_each_locked([&] (Signal_context &context) {
|
||||
|
||||
if (!context._pending) return;
|
||||
if (!context._pending) return false;
|
||||
|
||||
_contexts.head(context._next);
|
||||
context._pending = false;
|
||||
@ -166,7 +166,7 @@ Signal Signal_receiver::pending_signal()
|
||||
context._curr_signal = Signal::Data(0, 0);
|
||||
|
||||
Trace::Signal_received trace_event(context, result.num);
|
||||
throw Context_ring::Break_for_each();
|
||||
return true;
|
||||
});
|
||||
if (result.context) {
|
||||
Mutex::Guard context_guard(result.context->_mutex);
|
||||
@ -178,7 +178,7 @@ Signal Signal_receiver::pending_signal()
|
||||
|
||||
/* look for pending signals */
|
||||
if (Kernel::pending_signal(Capability_space::capid(_cap)) != 0) {
|
||||
throw Signal_not_pending();
|
||||
return Signal();
|
||||
}
|
||||
|
||||
/* read signal data */
|
||||
|
@ -88,7 +88,12 @@ class Genode::Signal
|
||||
*/
|
||||
Data() : context(0), num(0) { }
|
||||
|
||||
} _data;
|
||||
} _data { };
|
||||
|
||||
/**
|
||||
* Constructor for invalid signal
|
||||
*/
|
||||
Signal() { };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -117,6 +122,7 @@ class Genode::Signal
|
||||
|
||||
Signal_context *context() { return _data.context; }
|
||||
unsigned num() const { return _data.num; }
|
||||
bool valid() const { return _data.context != nullptr; }
|
||||
};
|
||||
|
||||
|
||||
@ -299,9 +305,7 @@ class Genode::Signal_receiver : Noncopyable
|
||||
|
||||
do {
|
||||
Mutex::Guard mutex_guard(context->_mutex);
|
||||
try {
|
||||
functor(*context);
|
||||
} catch (Break_for_each) { return; }
|
||||
if (functor(*context)) return;
|
||||
context = context->_next;
|
||||
} while (context != _head);
|
||||
}
|
||||
@ -352,7 +356,6 @@ class Genode::Signal_receiver : Noncopyable
|
||||
*/
|
||||
class Context_already_in_use { };
|
||||
class Context_not_associated { };
|
||||
class Signal_not_pending { };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -403,8 +406,7 @@ class Genode::Signal_receiver : Noncopyable
|
||||
/**
|
||||
* Retrieve pending signal
|
||||
*
|
||||
* \throw 'Signal_not_pending' no pending signal found
|
||||
* \return received signal
|
||||
* \return received signal (invalid if no pending signal found)
|
||||
*/
|
||||
Signal pending_signal();
|
||||
|
||||
|
@ -50,6 +50,6 @@ void Signal_receiver::block_for_signal()
|
||||
}
|
||||
|
||||
Signal Signal_receiver::pending_signal() {
|
||||
throw Signal_not_pending(); }
|
||||
return Signal(); }
|
||||
|
||||
void Signal_receiver::local_submit(Signal::Data) { ASSERT_NEVER_CALLED; }
|
||||
|
@ -55,15 +55,17 @@ void Entrypoint::Signal_proxy_component::signal()
|
||||
* Note, we handle only one signal here to ensure fairness between RPCs and
|
||||
* signals.
|
||||
*/
|
||||
try {
|
||||
|
||||
Signal sig = ep._sig_rec->pending_signal();
|
||||
|
||||
if (sig.valid()) {
|
||||
ep._dispatch_signal(sig);
|
||||
|
||||
if (sig.context()->level() == Signal_context::Level::Io) {
|
||||
/* trigger the progress handler */
|
||||
io_progress = true;
|
||||
}
|
||||
} catch (Signal_receiver::Signal_not_pending) { }
|
||||
}
|
||||
|
||||
if (io_progress)
|
||||
ep._handle_io_progress();
|
||||
@ -185,9 +187,10 @@ bool Entrypoint::_wait_and_dispatch_one_io_signal(bool const dont_block)
|
||||
|
||||
for (;;) {
|
||||
|
||||
try {
|
||||
Signal sig = _sig_rec->pending_signal();
|
||||
|
||||
if (sig.valid()) {
|
||||
|
||||
/* defer application-level signals */
|
||||
if (sig.context()->level() == Signal_context::Level::App) {
|
||||
_defer_signal(sig);
|
||||
@ -196,8 +199,8 @@ bool Entrypoint::_wait_and_dispatch_one_io_signal(bool const dont_block)
|
||||
|
||||
_dispatch_signal(sig);
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (Signal_receiver::Signal_not_pending) {
|
||||
if (dont_block)
|
||||
return false;
|
||||
|
||||
@ -231,7 +234,6 @@ bool Entrypoint::_wait_and_dispatch_one_io_signal(bool const dont_block)
|
||||
_sig_rec->block_for_signal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* initiate potential deferred-signal handling in entrypoint */
|
||||
if (_deferred_signals.first()) {
|
||||
|
@ -235,13 +235,14 @@ void Signal_receiver::block_for_signal()
|
||||
_signal_available.down();
|
||||
}
|
||||
|
||||
|
||||
Signal Signal_receiver::pending_signal()
|
||||
{
|
||||
Mutex::Guard contexts_guard(_contexts_mutex);
|
||||
Signal::Data result;
|
||||
_contexts.for_each_locked([&] (Signal_context &context) {
|
||||
_contexts.for_each_locked([&] (Signal_context &context) -> bool {
|
||||
|
||||
if (!context._pending) return;
|
||||
if (!context._pending) return false;
|
||||
|
||||
_contexts.head(context._next);
|
||||
context._pending = false;
|
||||
@ -249,7 +250,7 @@ Signal Signal_receiver::pending_signal()
|
||||
context._curr_signal = Signal::Data(0, 0);
|
||||
|
||||
Trace::Signal_received trace_event(context, result.num);
|
||||
throw Context_ring::Break_for_each();
|
||||
return true;
|
||||
});
|
||||
if (result.context) {
|
||||
Mutex::Guard context_guard(result.context->_mutex);
|
||||
@ -268,10 +269,9 @@ Signal Signal_receiver::pending_signal()
|
||||
* signal, we may have increased the semaphore already. In this case
|
||||
* the signal-causing context is absent from the list.
|
||||
*/
|
||||
throw Signal_not_pending();
|
||||
return Signal();
|
||||
}
|
||||
|
||||
|
||||
void Signal_receiver::unblock_signal_waiter(Rpc_entrypoint &)
|
||||
{
|
||||
_signal_available.up();
|
||||
|
@ -149,9 +149,10 @@ Signal Signal_receiver::wait_for_signal()
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
try {
|
||||
return pending_signal();
|
||||
} catch (Signal_not_pending) { }
|
||||
Signal sig = pending_signal();
|
||||
|
||||
if (sig.valid())
|
||||
return sig;
|
||||
|
||||
/* block until the receiver has received a signal */
|
||||
block_for_signal();
|
||||
|
@ -160,8 +160,6 @@ extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
log("Upgrading memory for creation of "
|
||||
"thread '", Cstring(rtthread->szName), "'");
|
||||
cpu_connection(rtthread->enmType)->upgrade_ram(4096);
|
||||
} catch (Genode::Signal_receiver::Signal_not_pending) {
|
||||
error("signal not pending ?");
|
||||
} catch (Out_of_caps) {
|
||||
error("out of caps ...");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user