libc: support asynchronous monitor jobs

Issue #5302
This commit is contained in:
Christian Helmuth 2024-09-02 14:07:56 +02:00 committed by Norman Feske
parent 899893cd17
commit 45cee6e951
2 changed files with 50 additions and 3 deletions

View File

@ -17,6 +17,7 @@
#define _LIBC__INTERNAL__KERNEL_H_
/* base-internal includes */
#include <util/reconstructible.h>
#include <internal/call_func.h>
/* 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())

View File

@ -17,6 +17,7 @@
/* Genode includes */
#include <base/registry.h>
#include <util/reconstructible.h>
/* libc-internal includes */
#include <internal/types.h>
@ -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<Registry<Job>::Element> _async_element;
void _register_async(Registry<Job> &registry)
{
_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<Job>::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 */