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
This commit is contained in:
Norman Feske 2019-10-10 15:32:25 +02:00 committed by Christian Helmuth
parent a5bc031cca
commit 7549189f88
1 changed files with 36 additions and 1 deletions

View File

@ -84,6 +84,11 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system
return Config(Genode::Cstring(buf));
}
typedef Genode::Registered<Vfs_watch_handle> Registered_watch_handle;
typedef Genode::Registry<Registered_watch_handle> 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<Registered_watch_handle *>(handle));
}
};
#endif /* _INCLUDE__VFS__READONLY_VALUE_FILE_SYSTEM_H_ */