mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-01 08:48:20 +00:00
libc: dispatch pending signals at selective points
This commit is contained in:
parent
491be000ca
commit
b1c9db8a0d
@ -118,6 +118,7 @@ class Genode::Entrypoint : Genode::Noncopyable
|
||||
void _defer_signal(Signal &sig);
|
||||
void _process_deferred_signals();
|
||||
void _process_incoming_signals();
|
||||
bool _wait_and_dispatch_one_io_signal(bool dont_block);
|
||||
|
||||
Constructible<Signal_proxy_thread> _signal_proxy_thread;
|
||||
|
||||
@ -180,7 +181,21 @@ class Genode::Entrypoint : Genode::Noncopyable
|
||||
* receiver belongs to the calling entrypoint. Alternatively,
|
||||
* remove it.
|
||||
*/
|
||||
void wait_and_dispatch_one_io_signal();
|
||||
void wait_and_dispatch_one_io_signal()
|
||||
{
|
||||
_wait_and_dispatch_one_io_signal(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch single pending I/O-level signal (non-blocking)
|
||||
*
|
||||
* \return true if a pending signal was dispatched, false if no signal
|
||||
* was pending
|
||||
*/
|
||||
bool dispatch_pending_io_signal()
|
||||
{
|
||||
return _wait_and_dispatch_one_io_signal(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return RPC entrypoint
|
||||
|
@ -59,7 +59,7 @@ _ZN6Genode10Entrypoint16_dispatch_signalERNS_6SignalE T
|
||||
_ZN6Genode10Entrypoint16schedule_suspendEPFvvES2_ T
|
||||
_ZN6Genode10Entrypoint22Signal_proxy_component6signalEv T
|
||||
_ZN6Genode10Entrypoint25_process_incoming_signalsEv T
|
||||
_ZN6Genode10Entrypoint31wait_and_dispatch_one_io_signalEv T
|
||||
_ZN6Genode10Entrypoint32_wait_and_dispatch_one_io_signalEb T
|
||||
_ZN6Genode10Entrypoint6manageERNS_22Signal_dispatcher_baseE T
|
||||
_ZN6Genode10Entrypoint8dissolveERNS_22Signal_dispatcher_baseE T
|
||||
_ZN6Genode10EntrypointC1ERNS_3EnvE T
|
||||
|
@ -172,7 +172,7 @@ void Entrypoint::_process_incoming_signals()
|
||||
}
|
||||
|
||||
|
||||
void Entrypoint::wait_and_dispatch_one_io_signal()
|
||||
bool Entrypoint::_wait_and_dispatch_one_io_signal(bool const dont_block)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
@ -198,6 +198,11 @@ void Entrypoint::wait_and_dispatch_one_io_signal()
|
||||
|
||||
} catch (Signal_receiver::Signal_not_pending) {
|
||||
_signal_pending_lock.unlock();
|
||||
if (dont_block) {
|
||||
/* indicate that we leave wait_and_dispatch_one_io_signal */
|
||||
cmpxchg(&_signal_recipient, ENTRYPOINT, NONE);
|
||||
return false;
|
||||
}
|
||||
_sig_rec->block_for_signal();
|
||||
}
|
||||
}
|
||||
@ -212,6 +217,8 @@ void Entrypoint::wait_and_dispatch_one_io_signal()
|
||||
&Entrypoint::_handle_deferred_signals);
|
||||
Signal_transmitter(*_deferred_signal_handler).submit();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -389,7 +389,8 @@ struct Libc::Kernel
|
||||
|
||||
jmp_buf _kernel_context;
|
||||
jmp_buf _user_context;
|
||||
bool _valid_user_context = false;
|
||||
bool _valid_user_context = false;
|
||||
bool _dispatch_pending_io_signals = false;
|
||||
|
||||
Genode::Thread &_myself { *Genode::Thread::myself() };
|
||||
|
||||
@ -566,7 +567,7 @@ struct Libc::Kernel
|
||||
}
|
||||
|
||||
/*
|
||||
* During the supension of the application code a nested
|
||||
* During the suspension of the application code a nested
|
||||
* Libc::with_libc() call took place, which will be executed
|
||||
* before returning to the first Libc::with_libc() call.
|
||||
*/
|
||||
@ -624,7 +625,13 @@ struct Libc::Kernel
|
||||
/* _setjmp() returned after _longjmp() - user context suspended */
|
||||
|
||||
while ((!_app_returned) && (!_suspend_scheduled)) {
|
||||
_env.ep().wait_and_dispatch_one_io_signal();
|
||||
if (_dispatch_pending_io_signals) {
|
||||
/* dispatch pending signals but don't block */
|
||||
while (_env.ep().dispatch_pending_io_signal()) ;
|
||||
} else {
|
||||
/* block for signals */
|
||||
_env.ep().wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
|
||||
if (_resume_main_once && !_setjmp(_kernel_context))
|
||||
_switch_to_user();
|
||||
@ -686,6 +693,21 @@ struct Libc::Kernel
|
||||
: _pthreads.suspend_myself(check, timeout_ms);
|
||||
}
|
||||
|
||||
void dispatch_pending_io_signals()
|
||||
{
|
||||
if (!_main_context()) return;
|
||||
|
||||
if (!_setjmp(_user_context)) {
|
||||
_valid_user_context = true;
|
||||
_dispatch_pending_io_signals = true;
|
||||
_resume_main_once = true; /* afterwards resume main */
|
||||
_switch_to_kernel();
|
||||
} else {
|
||||
_valid_user_context = false;
|
||||
_dispatch_pending_io_signals = false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long current_time()
|
||||
{
|
||||
return _timer_accessor.timer().curr_time();
|
||||
@ -812,6 +834,13 @@ unsigned long Libc::suspend(Suspend_functor &s, unsigned long timeout_ms)
|
||||
return kernel->suspend(s, timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
void Libc::dispatch_pending_io_signals()
|
||||
{
|
||||
kernel->dispatch_pending_io_signals();
|
||||
}
|
||||
|
||||
|
||||
unsigned long Libc::current_time()
|
||||
{
|
||||
return kernel->current_time();
|
||||
|
@ -46,6 +46,8 @@ namespace Libc {
|
||||
struct Suspend_functor { virtual bool suspend() = 0; };
|
||||
unsigned long suspend(Suspend_functor &, unsigned long timeout_ms = 0UL);
|
||||
|
||||
void dispatch_pending_io_signals();
|
||||
|
||||
/**
|
||||
* Get time since startup in ms
|
||||
*/
|
||||
|
@ -446,6 +446,8 @@ ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
|
||||
ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
|
||||
::size_t count)
|
||||
{
|
||||
Libc::dispatch_pending_io_signals();
|
||||
|
||||
typedef Vfs::File_io_service::Read_result Result;
|
||||
|
||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user