diff --git a/repos/libports/src/lib/libc/internal/env.h b/repos/libports/src/lib/libc/internal/env.h index 53a462e7b1..815fe23184 100644 --- a/repos/libports/src/lib/libc/internal/env.h +++ b/repos/libports/src/lib/libc/internal/env.h @@ -64,8 +64,11 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor public: - Env_implementation(Genode::Env &env, Genode::Allocator &alloc) - : _env(env), _vfs_env(_env, alloc, _vfs_config()) { } + Env_implementation(Genode::Env &env, Genode::Allocator &alloc, + Vfs::Env::User &vfs_user) + : + _env(env), _vfs_env(_env, alloc, _vfs_config(), vfs_user) + { } Vfs::File_system &vfs() { return _vfs_env.root_dir(); } diff --git a/repos/libports/src/lib/libc/internal/kernel.h b/repos/libports/src/lib/libc/internal/kernel.h index 472ceaff22..6583d0eb39 100644 --- a/repos/libports/src/lib/libc/internal/kernel.h +++ b/repos/libports/src/lib/libc/internal/kernel.h @@ -151,7 +151,24 @@ struct Libc::Kernel final : Vfs::Io_response_handler, */ void reset_malloc_heap() override; - Env_implementation _libc_env { _env, _heap }; + /* io_progress_handler marker */ + bool _io_progressed = false; + + struct Vfs_user : Vfs::Env::User + { + bool &_io_progressed; + + Vfs_user(bool &io_progressed) : _io_progressed(io_progressed) { } + + void wakeup_vfs_user() override + { + _io_progressed = true; + } + }; + + Vfs_user _vfs_user { _io_progressed }; + + Env_implementation _libc_env { _env, _heap, _vfs_user }; bool const _update_mtime = _libc_env.libc_config().attribute_value("update_mtime", true); @@ -205,9 +222,6 @@ struct Libc::Kernel final : Vfs::Io_response_handler, jmp_buf _user_context; bool _valid_user_context = false; - /* io_progress_handler marker */ - bool _io_progressed { false }; - Thread &_myself { *Thread::myself() }; addr_t _kernel_stack = Thread::mystack().top; diff --git a/repos/os/include/vfs/env.h b/repos/os/include/vfs/env.h index 261f328be9..7f0586931a 100644 --- a/repos/os/include/vfs/env.h +++ b/repos/os/include/vfs/env.h @@ -60,6 +60,20 @@ struct Vfs::Env : Interface }; virtual Io &io() = 0; + + /** + * Interface for notifying the VFS user about possible progress + * + * This interface allows VFS plugins to prompt the potential unblocking of + * the VFS user, e.g., continuing a write operation that was stalled + * because of a saturated I/O buffer. + */ + struct User : Interface, Genode::Noncopyable + { + virtual void wakeup_vfs_user() = 0; + }; + + virtual User &user() = 0; }; #endif /* _INCLUDE__VFS__ENV_H_ */ diff --git a/repos/os/include/vfs/simple_env.h b/repos/os/include/vfs/simple_env.h index 08660cbd6b..9e905e7fff 100644 --- a/repos/os/include/vfs/simple_env.h +++ b/repos/os/include/vfs/simple_env.h @@ -22,12 +22,13 @@ namespace Vfs { struct Simple_env; } -class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io +class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io, private Vfs::Env::User { private: Genode::Env &_env; Genode::Allocator &_alloc; + Vfs::Env::User &_user; Global_file_system_factory _fs_factory { _alloc }; @@ -41,9 +42,15 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io Simple_env(Genode::Env &env, Genode::Allocator &alloc, - Genode::Xml_node config) + Genode::Xml_node config, + Vfs::Env::User &user) : - _env(env), _alloc(alloc), _root_dir(*this, config, _fs_factory) + _env(env), _alloc(alloc), _user(user), _root_dir(*this, config, _fs_factory) + { } + + Simple_env(Genode::Env &env, Genode::Allocator &alloc, Genode::Xml_node config) + : + Simple_env(env, alloc, config, *this) { } void apply_config(Genode::Xml_node const &config) @@ -56,6 +63,7 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io Vfs::File_system &root_dir() override { return _root_dir; } Deferred_wakeups &deferred_wakeups() override { return _deferred_wakeups; } Vfs::Env::Io &io() override { return *this; } + Vfs::Env::User &user() override { return _user; } /** * Vfs::Env::Io interface @@ -70,6 +78,14 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io _deferred_wakeups.trigger(); _env.ep().wait_and_dispatch_one_io_signal(); } + + /** + * Vfs::Env::User interface + * + * Fallback implementation used if no 'user' is specified at + * construction time. + */ + void wakeup_vfs_user() override { }; }; #endif /* _INCLUDE__VFS__SIMPLE_ENV_H_ */