vfs: support watch handlers on application signal level

Fixes #4092
This commit is contained in:
Christian Prochaska
2024-02-14 14:46:06 +01:00
committed by Christian Helmuth
parent a529fffb7b
commit 080d3b6b63
9 changed files with 79 additions and 26 deletions

View File

@ -103,8 +103,8 @@ struct Menu_view::Main
Directory _fonts_dir { _root_dir, "fonts" }; Directory _fonts_dir { _root_dir, "fonts" };
Directory _styles_dir { _root_dir, "styles" }; Directory _styles_dir { _root_dir, "styles" };
Style_database _styles { _env.ram(), _env.rm(), _heap, _fonts_dir, _styles_dir, Style_database _styles { _env.ep(), _env.ram(), _env.rm(), _heap,
_dialog_update_handler }; _fonts_dir, _styles_dir, _dialog_update_handler };
Animator _animator { }; Animator _animator { };

View File

@ -148,19 +148,21 @@ class Menu_view::Style_database
* *
* \throw Reading_failed * \throw Reading_failed
*/ */
Font_entry(Directory const &fonts_dir, Path const &path, Allocator &alloc, Font_entry(Entrypoint &ep, Directory const &fonts_dir,
Path const &path, Allocator &alloc,
Style_database const &style_database) Style_database const &style_database)
try : try :
path(path), path(path),
_style_database(style_database), _style_database(style_database),
_vfs_font(alloc, fonts_dir, path), _vfs_font(alloc, fonts_dir, path),
_cached_font(alloc, _vfs_font, _font_cache_limit), _cached_font(alloc, _vfs_font, _font_cache_limit),
_glyphs_changed_handler(fonts_dir, Path(path, "/glyphs"), _glyphs_changed_handler(ep, fonts_dir, Path(path, "/glyphs"),
*this, &Font_entry::_handle_glyphs_changed) *this, &Font_entry::_handle_glyphs_changed)
{ } { }
catch (...) { throw Reading_failed(); } catch (...) { throw Reading_failed(); }
}; };
Entrypoint &_ep;
Ram_allocator &_ram; Ram_allocator &_ram;
Region_map &_rm; Region_map &_rm;
Allocator &_alloc; Allocator &_alloc;
@ -228,11 +230,12 @@ class Menu_view::Style_database
public: public:
Style_database(Ram_allocator &ram, Region_map &rm, Allocator &alloc, Style_database(Entrypoint &ep, Ram_allocator &ram, Region_map &rm,
Allocator &alloc,
Directory const &fonts_dir, Directory const &styles_dir, Directory const &fonts_dir, Directory const &styles_dir,
Signal_context_capability style_changed_sigh) Signal_context_capability style_changed_sigh)
: :
_ram(ram), _rm(rm), _alloc(alloc), _ep(ep), _ram(ram), _rm(rm), _alloc(alloc),
_fonts_dir(fonts_dir), _styles_dir(styles_dir), _fonts_dir(fonts_dir), _styles_dir(styles_dir),
_style_changed_sigh(style_changed_sigh) _style_changed_sigh(style_changed_sigh)
{ } { }
@ -273,7 +276,7 @@ class Menu_view::Style_database
*/ */
try { try {
Font_entry *e = new (_alloc) Font_entry *e = new (_alloc)
Font_entry(_fonts_dir, path, _alloc, *this); Font_entry(_ep, _fonts_dir, path, _alloc, *this);
_fonts.insert(e); _fonts.insert(e);
return &e->font(); return &e->font();

View File

@ -136,7 +136,8 @@ struct Text_area::Main : Text_area_widget::Action
void _watch(bool enabled) void _watch(bool enabled)
{ {
_watch_handler.conditional(enabled, _vfs, _path(), *this, &Main::_handle_watch); _watch_handler.conditional(enabled, _env.ep(), _vfs, _path(), *this,
&Main::_handle_watch);
} }
bool _editable() const { return !_watch_handler.constructed(); } bool _editable() const { return !_watch_handler.constructed(); }

View File

@ -279,12 +279,12 @@ class Vfs_trace::Subject : private Subject_factory,
typedef String<200> Config; typedef String<200> Config;
Watch_handler<Subject> _enable_handler { Io::Watch_handler<Subject> _enable_handler {
_enabled_fs, "/enable", _enabled_fs, "/enable",
Subject_factory::_env.alloc(), Subject_factory::_env.alloc(),
*this, &Subject::_enable_subject }; *this, &Subject::_enable_subject };
Watch_handler<Subject> _buffer_size_handler { Io::Watch_handler<Subject> _buffer_size_handler {
_buffer_size_fs, "/buffer_size", _buffer_size_fs, "/buffer_size",
Subject_factory::_env.alloc(), Subject_factory::_env.alloc(),
*this, &Subject::_buffer_size }; *this, &Subject::_buffer_size };

View File

@ -80,8 +80,15 @@ struct Terminal::Main : Character_consumer
_config_handler.local_submit(); _config_handler.local_submit();
} }
Watch_handler<Main> _glyphs_changed_handler { /*
_root_dir, "fonts/monospace/regular/glyphs", *this, &Main::_handle_glyphs_changed }; * XXX Currently an I/O-level watch handler is used
* to prevent a config/watch handler cycle as
* side-effect of '_root_dir.apply_config()' with
* an application-level watch handler.
*/
Io::Watch_handler<Main> _glyphs_changed_handler {
_root_dir, "fonts/monospace/regular/glyphs", *this,
&Main::_handle_glyphs_changed };
Color_palette _color_palette { }; Color_palette _color_palette { };

View File

@ -202,12 +202,12 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
Constructible<Rtc> _rtc { }; Constructible<Rtc> _rtc { };
/* handler for watching the stdout's info pseudo file */ /* handler for watching the stdout's info pseudo file */
Constructible<Watch_handler<Kernel>> _terminal_resize_handler { }; Constructible<Io::Watch_handler<Kernel>> _terminal_resize_handler { };
void _handle_terminal_resize(); void _handle_terminal_resize();
/* handler for watching user interrupts (control-c) */ /* handler for watching user interrupts (control-c) */
Constructible<Watch_handler<Kernel>> _user_interrupt_handler { }; Constructible<Io::Watch_handler<Kernel>> _user_interrupt_handler { };
void _handle_user_interrupt(); void _handle_user_interrupt();

View File

@ -813,55 +813,55 @@ struct Vfs::Oss_file_system::Local_factory : File_system_factory
Audio _audio { _env.env(), _info, _info_fs }; Audio _audio { _env.env(), _info, _info_fs };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _enable_input_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _enable_input_handler {
_enable_input_fs, "/enable_input", _enable_input_fs, "/enable_input",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_enable_input_changed }; &Vfs::Oss_file_system::Local_factory::_enable_input_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _enable_output_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _enable_output_handler {
_enable_output_fs, "/enable_output", _enable_output_fs, "/enable_output",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_enable_output_changed }; &Vfs::Oss_file_system::Local_factory::_enable_output_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _halt_input_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _halt_input_handler {
_halt_input_fs, "/halt_input", _halt_input_fs, "/halt_input",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_halt_input_changed }; &Vfs::Oss_file_system::Local_factory::_halt_input_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _halt_output_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _halt_output_handler {
_halt_output_fs, "/halt_output", _halt_output_fs, "/halt_output",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_halt_output_changed }; &Vfs::Oss_file_system::Local_factory::_halt_output_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _ifrag_total_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _ifrag_total_handler {
_ifrag_total_fs, "/ifrag_total", _ifrag_total_fs, "/ifrag_total",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_ifrag_total_changed }; &Vfs::Oss_file_system::Local_factory::_ifrag_total_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _ifrag_size_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _ifrag_size_handler {
_ifrag_size_fs, "/ifrag_size", _ifrag_size_fs, "/ifrag_size",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_ofrag_size_changed }; &Vfs::Oss_file_system::Local_factory::_ofrag_size_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _ofrag_total_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _ofrag_total_handler {
_ofrag_total_fs, "/ofrag_total", _ofrag_total_fs, "/ofrag_total",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_ofrag_total_changed }; &Vfs::Oss_file_system::Local_factory::_ofrag_total_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _ofrag_size_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _ofrag_size_handler {
_ofrag_size_fs, "/ofrag_size", _ofrag_size_fs, "/ofrag_size",
_env.alloc(), _env.alloc(),
*this, *this,
&Vfs::Oss_file_system::Local_factory::_ofrag_size_changed }; &Vfs::Oss_file_system::Local_factory::_ofrag_size_changed };
Genode::Watch_handler<Vfs::Oss_file_system::Local_factory> _play_underruns_handler { Genode::Io::Watch_handler<Vfs::Oss_file_system::Local_factory> _play_underruns_handler {
_play_underruns_fs, "/play_underruns", _play_underruns_fs, "/play_underruns",
_env.alloc(), _env.alloc(),
*this, *this,

View File

@ -31,6 +31,10 @@ namespace Genode {
class Append_file; class Append_file;
class New_file; class New_file;
class Watcher; class Watcher;
namespace Io {
template <typename>
class Watch_handler;
}
template <typename> template <typename>
class Watch_handler; class Watch_handler;
template <typename FN> template <typename FN>
@ -954,9 +958,12 @@ class Genode::Watcher
}; };
/**
* Watch handler that operates on I/O signal level
*/
template <typename T> template <typename T>
class Genode::Watch_handler : public Vfs::Watch_response_handler, class Genode::Io::Watch_handler : public Vfs::Watch_response_handler,
private Watcher private Watcher
{ {
private: private:
@ -981,4 +988,39 @@ class Genode::Watch_handler : public Vfs::Watch_response_handler,
void watch_response() override { (_obj.*_member)(); } void watch_response() override { (_obj.*_member)(); }
}; };
/**
* Watch handler that operates on application signal level
*/
template <typename T>
class Genode::Watch_handler : public Signal_handler<Watch_handler<T>>
{
private:
Io::Watch_handler<Watch_handler> _io_watch_handler;
T &_obj;
void (T::*_member) ();
void _handle_watch_response()
{
Signal_handler<Watch_handler<T>>::local_submit();
}
void _handle_signal()
{
(_obj.*_member)();
}
public:
Watch_handler(Genode::Entrypoint &ep, Directory const &dir,
Directory::Path const &rel_path,
T &obj, void (T::*member)())
: Signal_handler<Watch_handler<T>>(ep, *this, &Watch_handler<T>::_handle_signal),
_io_watch_handler(dir, rel_path, *this, &Watch_handler<T>::_handle_watch_response),
_obj(obj), _member(member)
{ }
};
#endif /* _INCLUDE__OS__VFS_H_ */ #endif /* _INCLUDE__OS__VFS_H_ */

View File

@ -244,7 +244,7 @@ struct Vfs::Tap_file_system::Local_factory : File_system_factory,
** Watch handlers ** ** Watch handlers **
********************/ ********************/
Genode::Watch_handler<Vfs::Tap_file_system::Local_factory<FS>> _mac_addr_changed_handler { Genode::Io::Watch_handler<Vfs::Tap_file_system::Local_factory<FS>> _mac_addr_changed_handler {
_mac_addr_fs, "/mac_addr", _mac_addr_fs, "/mac_addr",
_env.alloc(), _env.alloc(),
*this, *this,