From 7549189f882620f32ba4f6e5bcc4e437203e05fa Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 10 Oct 2019 15:32:25 +0200 Subject: [PATCH] vfs: watch support for Readonly_value_file_system This patch adds support for watch notifications for the 'Readonly_value_file_system', which is often used by VFS plugins to implement pseudo files. It thereby enables VFS clients to respond to VFS-plugin events (think of terminal resize) dynamically. Fixes #3523 --- .../include/vfs/readonly_value_file_system.h | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/repos/os/include/vfs/readonly_value_file_system.h b/repos/os/include/vfs/readonly_value_file_system.h index d4971a149..6ca1cab33 100644 --- a/repos/os/include/vfs/readonly_value_file_system.h +++ b/repos/os/include/vfs/readonly_value_file_system.h @@ -84,6 +84,11 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system return Config(Genode::Cstring(buf)); } + typedef Genode::Registered Registered_watch_handle; + typedef Genode::Registry Watch_handle_registry; + + Watch_handle_registry _handle_registry { }; + public: Readonly_value_file_system(Name const &name, T const &initial_value) @@ -99,7 +104,13 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system char const *type() override { return type_name(); } - void value(T const &value) { _buffer = Buffer(value); } + void value(T const &value) + { + _buffer = Buffer(value); + + _handle_registry.for_each([this] (Registered_watch_handle &handle) { + handle.watch_response(); }); + } bool matches(Xml_node node) const { @@ -107,6 +118,7 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system node.attribute_value("name", Name()) == _file_name; } + /********************************* ** Directory-service interface ** *********************************/ @@ -134,6 +146,29 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system out.size = _buffer.length(); return result; } + + Watch_result watch(char const *path, + Vfs_watch_handle **handle, + Allocator &alloc) override + { + if (!_single_file(path)) + return WATCH_ERR_UNACCESSIBLE; + + try { + *handle = new (alloc) + Registered_watch_handle(_handle_registry, *this, alloc); + + return WATCH_OK; + } + catch (Genode::Out_of_ram) { return WATCH_ERR_OUT_OF_RAM; } + catch (Genode::Out_of_caps) { return WATCH_ERR_OUT_OF_CAPS; } + } + + void close(Vfs_watch_handle *handle) override + { + Genode::destroy(handle->alloc(), + static_cast(handle)); + } }; #endif /* _INCLUDE__VFS__READONLY_VALUE_FILE_SYSTEM_H_ */