mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
Add Io_progress_handler to Entrypoint interface
The "schedule_post_signal_hook" method of the Genode::Entrypoint class is problematic because the signal hook can be scheduled and replaced multiple times during the signal dispatch cycle. Add an alternative to this method with "register_io_progress_handler" and the "Post_signal_ hook" class with "Io_progress_handler". The difference being an "Io_progress_handler" may be registered once during the lifetime of an entrypoint to prevent arbitrary libraries from replacing a pending hook. The "register_io_progress_handler" remains as a deprecated API, and is now invoked for every I/O signal received and only for I/O signals rather than for any signal. Ref #3132
This commit is contained in:
committed by
Christian Helmuth
parent
93fb79f357
commit
57fd4e9148
@ -370,8 +370,7 @@ class Vfs::Fs_file_system : public File_system
|
||||
Io_response_handler &_io_handler;
|
||||
Watch_response_handler &_watch_handler;
|
||||
List<Vfs_handle::Context> _context_list { };
|
||||
List<Vfs_watch_handle::Context>
|
||||
_watch_context_list { };
|
||||
|
||||
Lock _list_lock { };
|
||||
bool _notify_all { false };
|
||||
|
||||
@ -406,27 +405,6 @@ class Vfs::Fs_file_system : public File_system
|
||||
_ep.schedule_post_signal_hook(this);
|
||||
}
|
||||
|
||||
void arm_watch_event(Vfs_watch_handle::Context &context)
|
||||
{
|
||||
{
|
||||
Lock::Guard list_guard(_list_lock);
|
||||
|
||||
for (Vfs_watch_handle::Context *list_context = _watch_context_list.first();
|
||||
list_context;
|
||||
list_context = list_context->next())
|
||||
{
|
||||
if (list_context == &context) {
|
||||
/* already in list */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_watch_context_list.insert(&context);
|
||||
}
|
||||
|
||||
_ep.schedule_post_signal_hook(this);
|
||||
}
|
||||
|
||||
void function() override
|
||||
{
|
||||
Vfs_handle::Context *context = nullptr;
|
||||
@ -451,18 +429,6 @@ class Vfs::Fs_file_system : public File_system
|
||||
|
||||
/* done if no contexts and all notified */
|
||||
} while (context);
|
||||
|
||||
for (;;) {
|
||||
Vfs_watch_handle::Context *context = nullptr;
|
||||
{
|
||||
Lock::Guard list_guard(_list_lock);
|
||||
|
||||
context = _watch_context_list.first();
|
||||
if (!context) break;
|
||||
_watch_context_list.remove(context);
|
||||
_watch_handler.handle_watch_response(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -609,9 +575,14 @@ class Vfs::Fs_file_system : public File_system
|
||||
|
||||
try {
|
||||
if (packet.operation() == Packet_descriptor::CONTENT_CHANGED) {
|
||||
/*
|
||||
* Trigger the watch response during signal dispatch.
|
||||
* This is incompatible with the Libc I/O handling
|
||||
* but the Libc does not open watch handles and shall
|
||||
* not use them before Post_signal_hook is removed.
|
||||
*/
|
||||
_watch_handle_space.apply<Fs_vfs_watch_handle>(id, [&] (Fs_vfs_watch_handle &handle) {
|
||||
if (auto *ctx = handle.context())
|
||||
_post_signal_hook.arm_watch_event(*ctx); });
|
||||
_env.watch_handler().handle_watch_response(handle.context()); });
|
||||
} else {
|
||||
_handle_space.apply<Fs_vfs_handle>(id, handle_read);
|
||||
}
|
||||
|
Reference in New Issue
Block a user