From e33d65aea0e08087cde8bd1bc037229111411f7f Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Mon, 3 Apr 2017 10:18:23 +0200 Subject: [PATCH] libc: test nested signal handling and RPC Issue #2363 --- .../libports/src/test/libc_component/main.cc | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/repos/libports/src/test/libc_component/main.cc b/repos/libports/src/test/libc_component/main.cc index 0fb66ac66..0cb224df0 100644 --- a/repos/libports/src/test/libc_component/main.cc +++ b/repos/libports/src/test/libc_component/main.cc @@ -14,10 +14,12 @@ /* Genode includes */ #include #include +#include #include #include #include #include +#include /* libc includes */ #include @@ -32,6 +34,7 @@ namespace Log { using Genode::Static_root; using Genode::Log_session; + using Genode::Signal_handler; struct Session_component; struct Main; @@ -74,11 +77,24 @@ static void use_file_system() struct Log::Session_component : Genode::Rpc_object { + Libc::Env &_env; + Timer::Connection _timer { _env }; + + Signal_handler _timer_handler { + _env.ep(), *this, &Session_component::_handle_timer }; + + void _handle_timer() + { + if (_in_read) + Genode::error("timer fired during read?"); + } + char _buf[Log_session::MAX_STRING_LEN]; int _fd = -1; fd_set _readfds; fd_set _writefds; fd_set _exceptfds; + bool _in_read = false; void _select() { @@ -97,6 +113,24 @@ struct Log::Session_component : Genode::Rpc_object Libc::Select_handler _select_handler { *this, &Session_component::_select_ready }; + void _read() + { + _in_read = true; + + /* never mind the potentially nested with_libc */ + Libc::with_libc([&] () { + int const result = read(_fd, _buf, sizeof(_buf)-1); + if (result <= 0) { + Genode::warning("read returned ", result, " in select handler"); + return; + } + _buf[result] = 0; + Genode::log("read from file \"", Genode::Cstring(_buf), "\""); + }); + + _in_read = false; + } + void _select_ready(int nready, fd_set const &readfds, fd_set const &writefds, fd_set const &exceptfds) { Libc::with_libc([&] () { @@ -116,17 +150,11 @@ struct Log::Session_component : Genode::Rpc_object return; } - int const result = read(_fd, _buf, sizeof(_buf)-1); - if (result <= 0) { - Genode::warning("read returned ", result, " in select handler"); - return; - } - _buf[result] = 0; - Genode::log("read from file \"", Genode::Cstring(_buf), "\""); + _read(); }); } - Session_component() + Session_component(Libc::Env &env) : _env(env) { Libc::with_libc([&] () { _fd = open("/dev/terminal", O_RDWR); @@ -137,6 +165,12 @@ struct Log::Session_component : Genode::Rpc_object FD_ZERO(&_exceptfds); FD_SET(_fd, &_readfds); }); + + _timer.sigh(_timer_handler); + _timer.trigger_periodic(500*1000); + + /* initially call read two times to ensure blocking */ + _read(); _read(); } Genode::size_t write(String const &string_buf) @@ -160,7 +194,7 @@ struct Log::Session_component : Genode::Rpc_object struct Log::Main { Libc::Env &_env; - Session_component _session { }; + Session_component _session { _env }; Static_root _root { _env.ep().manage(_session) }; Main(Libc::Env &env) : _env(env)