mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-13 04:38:20 +00:00
Notification support for the VFS library
Add a new 'Vfs_watch_handle' type to the VFS interface. This handle type will pass a handle context up through the I/O handler to the application when a notification event occurs. Watch support implemented for RAM and File_system plugins, all other file-systems return WATCH_ERR_STATIC by default. Test at run/fs_rom_update_ram and run/fs_rom_update_fs. Fix #1934
This commit is contained in:
committed by
Christian Helmuth
parent
344d46ce78
commit
9c6b720ec1
@ -94,6 +94,47 @@ class Vfs::Dir_file_system : public File_system
|
||||
Dir_vfs_handle &operator = (Dir_vfs_handle const &);
|
||||
};
|
||||
|
||||
struct Dir_watch_handle : Vfs_watch_handle
|
||||
{
|
||||
struct Watch_handle_element;
|
||||
|
||||
typedef Genode::Registry<Watch_handle_element> Watch_handle_registry;
|
||||
|
||||
struct Watch_handle_element : Watch_handle_registry::Element
|
||||
{
|
||||
Vfs_watch_handle &watch_handle;
|
||||
Watch_handle_element(Watch_handle_registry ®istry,
|
||||
Vfs_watch_handle &handle)
|
||||
: Watch_handle_registry::Element(registry, *this),
|
||||
watch_handle(handle) { }
|
||||
};
|
||||
|
||||
Watch_handle_registry handle_registry { };
|
||||
|
||||
Dir_watch_handle(File_system &fs, Genode::Allocator &alloc)
|
||||
: Vfs_watch_handle(fs, alloc) { }
|
||||
|
||||
~Dir_watch_handle()
|
||||
{
|
||||
/* close all sub-handles */
|
||||
auto f = [&] (Watch_handle_element &e) {
|
||||
e.watch_handle.fs().close(&e.watch_handle);
|
||||
destroy(alloc(), &e);
|
||||
};
|
||||
handle_registry.for_each(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate the handle context to each sub-handle
|
||||
*/
|
||||
void context(Context *ctx) override
|
||||
{
|
||||
handle_registry.for_each( [&] (Watch_handle_element &elem) {
|
||||
elem.watch_handle.context(ctx); } );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* pointer to first child file system */
|
||||
File_system *_first_file_system = nullptr;
|
||||
|
||||
@ -733,6 +774,41 @@ class Vfs::Dir_file_system : public File_system
|
||||
destroy(handle->alloc(), handle);
|
||||
}
|
||||
|
||||
Watch_result watch(char const *path,
|
||||
Vfs_watch_handle **handle,
|
||||
Allocator &alloc) override
|
||||
{
|
||||
/* static by default, no allocations */
|
||||
Watch_result r = WATCH_ERR_STATIC;
|
||||
Dir_watch_handle *meta_handle = nullptr;
|
||||
|
||||
for (File_system *fs = _first_file_system; fs; fs = fs->next) {
|
||||
Vfs_watch_handle *sub_handle;
|
||||
|
||||
if (fs->watch(path, &sub_handle, alloc) == WATCH_OK) {
|
||||
if (meta_handle == nullptr) {
|
||||
/* at least one non-static FS, allocate handle */
|
||||
meta_handle = new (alloc) Dir_watch_handle(*this, alloc);
|
||||
*handle = meta_handle;
|
||||
r = WATCH_OK;
|
||||
}
|
||||
|
||||
/* attach child FS handle to returned handle */
|
||||
new (alloc)
|
||||
Dir_watch_handle::Watch_handle_element(
|
||||
meta_handle->handle_registry, *sub_handle);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void close(Vfs_watch_handle *handle) override
|
||||
{
|
||||
if (handle && (&handle->fs() == this))
|
||||
destroy(handle->alloc(), handle);
|
||||
}
|
||||
|
||||
Unlink_result unlink(char const *path) override
|
||||
{
|
||||
auto unlink_fn = [] (File_system &fs, char const *path)
|
||||
|
Reference in New Issue
Block a user