diff --git a/repos/libports/src/lib/libc/internal/init.h b/repos/libports/src/lib/libc/internal/init.h index 1fdb82a1d5..4c36e43ce3 100644 --- a/repos/libports/src/lib/libc/internal/init.h +++ b/repos/libports/src/lib/libc/internal/init.h @@ -107,7 +107,7 @@ namespace Libc { /** * Socket fs */ - void init_socket_fs(Suspend &); + void init_socket_fs(Suspend &, Monitor &); /** * Pthread/semaphore support diff --git a/repos/libports/src/lib/libc/kernel.cc b/repos/libports/src/lib/libc/kernel.cc index 78493a23cb..ac208b223e 100644 --- a/repos/libports/src/lib/libc/kernel.cc +++ b/repos/libports/src/lib/libc/kernel.cc @@ -477,7 +477,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap) init_file_operations(*this, _libc_env); init_time(*this, *this); init_select(*this, _signal, *this); - init_socket_fs(*this); + init_socket_fs(*this, *this); init_passwd(_passwd_config()); init_signal(_signal); diff --git a/repos/libports/src/lib/libc/socket_fs_plugin.cc b/repos/libports/src/lib/libc/socket_fs_plugin.cc index 5b8c46fcb8..d5db46ff83 100644 --- a/repos/libports/src/lib/libc/socket_fs_plugin.cc +++ b/repos/libports/src/lib/libc/socket_fs_plugin.cc @@ -36,6 +36,7 @@ #include /* libc-internal includes */ +#include #include #include #include @@ -52,14 +53,28 @@ namespace Libc { static Libc::Suspend *_suspend_ptr; +static Libc::Monitor *_monitor_ptr; -void Libc::init_socket_fs(Suspend &suspend) +void Libc::init_socket_fs(Suspend &suspend, Monitor &monitor) { _suspend_ptr = &suspend; + _monitor_ptr = &monitor; } +static Libc::Monitor & monitor() +{ + struct Missing_call_of_init_socket_fs : Genode::Exception { }; + if (!_monitor_ptr) + throw Missing_call_of_init_socket_fs(); + return *_monitor_ptr; +} + + +namespace { using Fn = Libc::Monitor::Function_result; } + + /*************** ** Utilities ** ***************/ @@ -1229,43 +1244,53 @@ int Socket_fs::Plugin::select(int nfds, FD_ZERO(writefds); FD_ZERO(exceptfds); - for (int fd = 0; fd < nfds; ++fd) { + auto fn = [&] { - bool fd_in_readfds = FD_ISSET(fd, &in_readfds); - bool fd_in_writefds = FD_ISSET(fd, &in_writefds); + for (int fd = 0; fd < nfds; ++fd) { - if (!fd_in_readfds && !fd_in_writefds) - continue; + bool fd_in_readfds = FD_ISSET(fd, &in_readfds); + bool fd_in_writefds = FD_ISSET(fd, &in_writefds); - File_descriptor *fdo = file_descriptor_allocator()->find_by_libc_fd(fd); + if (!fd_in_readfds && !fd_in_writefds) + continue; - /* handle only fds that belong to this plugin */ - if (!fdo || (fdo->plugin != this)) - continue; + File_descriptor *fdo = file_descriptor_allocator()->find_by_libc_fd(fd); - if (fd_in_readfds) { - try { - Socket_fs::Context *context = dynamic_cast(fdo->context); + /* handle only fds that belong to this plugin */ + if (!fdo || (fdo->plugin != this)) + continue; - if (context->read_ready()) { - FD_SET(fd, readfds); - ++nready; - } - } catch (Socket_fs::Context::Inaccessible) { } + if (fd_in_readfds) { + try { + Socket_fs::Context *context = dynamic_cast(fdo->context); + + if (context->read_ready()) { + FD_SET(fd, readfds); + ++nready; + } + } catch (Socket_fs::Context::Inaccessible) { } + } + + if (fd_in_writefds) { + try { + Socket_fs::Context *context = dynamic_cast(fdo->context); + + if (context->write_ready()) { + FD_SET(fd, writefds); + ++nready; + } + } catch (Socket_fs::Context::Inaccessible) { } + } + + /* XXX exceptfds not supported */ } + return Fn::COMPLETE; + }; - if (fd_in_writefds) { - try { - Socket_fs::Context *context = dynamic_cast(fdo->context); - - if (context->write_ready()) { - FD_SET(fd, writefds); - ++nready; - } - } catch (Socket_fs::Context::Inaccessible) { } - } - - /* XXX exceptfds not supported */ + if (Libc::Kernel::kernel().main_context() && Libc::Kernel::kernel().main_suspended()) { + fn(); + } else { + monitor().monitor(fn); } return nready;