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:
Emery Hemingway
2019-02-05 15:31:21 +01:00
committed by Christian Helmuth
parent 93fb79f357
commit 57fd4e9148
5 changed files with 134 additions and 116 deletions

View File

@ -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);
}