diff --git a/repos/libports/src/lib/libc/internal/kernel.h b/repos/libports/src/lib/libc/internal/kernel.h index 2b632a93c7..1261736495 100644 --- a/repos/libports/src/lib/libc/internal/kernel.h +++ b/repos/libports/src/lib/libc/internal/kernel.h @@ -17,6 +17,7 @@ #define _LIBC__INTERNAL__KERNEL_H_ /* base-internal includes */ +#include #include /* libc includes */ @@ -584,6 +585,14 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler, } } + /** + * Monitor interface + */ + void monitor_async(Job &job) override + { + _monitors.monitor_async(job); + } + void _trigger_monitor_examination() override { if (_main_context()) diff --git a/repos/libports/src/lib/libc/internal/monitor.h b/repos/libports/src/lib/libc/internal/monitor.h index 228ea0f8cf..ac6cef1207 100644 --- a/repos/libports/src/lib/libc/internal/monitor.h +++ b/repos/libports/src/lib/libc/internal/monitor.h @@ -17,6 +17,7 @@ /* Genode includes */ #include +#include /* libc-internal includes */ #include @@ -82,6 +83,13 @@ class Libc::Monitor : Interface return _monitor(function, timeout_ms); } + /** + * Monitor asynchronous job execution + * + * Returns immediately after the job is registered for execution. + */ + virtual void monitor_async(Job &job) = 0; + /** * Trigger examination of monitored functions */ @@ -89,19 +97,32 @@ class Libc::Monitor : Interface }; -struct Libc::Monitor::Job +class Libc::Monitor::Job { private: + friend class Pool; + Monitor::Function &_fn; Blockade &_blockade; + Constructible::Element> _async_element; + + void _register_async(Registry ®istry) + { + _async_element.construct(registry, *this); + } + public: Job(Monitor::Function &fn, Blockade &blockade) : _fn(fn), _blockade(blockade) { } - virtual ~Job() { } + virtual ~Job() + { + if (_async_element.constructed()) + _async_element.destruct(); + } bool execute() { return _fn.execute() == Function_result::COMPLETE; } @@ -124,7 +145,12 @@ struct Libc::Monitor::Pool Pool(Monitor &monitor) : _monitor(monitor) { } - /* called by monitor-user context */ + /** + * Monitor synchronous job execution + * + * The function is called by the monitor-user context and returns after + * job completion. + */ void monitor(Job &job) { Registry::Element element { _jobs, job }; @@ -134,6 +160,18 @@ struct Libc::Monitor::Pool job.wait_for_completion(); } + /** + * Monitor asynchronous job execution + * + * The function is called by the monitor-user context and returns after + * job is registered for execution. Jobs are removed from the pool on + * destruction. + */ + void monitor_async(Job &job) + { + job._register_async(_jobs); + } + enum class State { JOBS_PENDING, ALL_COMPLETE }; /* called by the monitor context itself */