L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
errand.h
1/*
2 * Copyright (C) 2014, 2020 Kernkonzept GmbH.
3 * Author(s): Sarah Hoffmann <sarah.hoffmann@kernkonzept.com>
4 *
5 * This file is distributed under the terms of the GNU General Public
6 * License, version 2. Please see the COPYING-GPL-2 file for details.
7 *
8 * As a special exception, you may use this file as part of a free software
9 * library without restriction. Specifically, if other files instantiate
10 * templates or use macros or inline functions from this file, or you compile
11 * this file and link it with other files to produce an executable, this
12 * file does not by itself cause the resulting executable to be covered by
13 * the GNU General Public License. This exception does not however
14 * invalidate any other reasons why the executable file might be covered by
15 * the GNU General Public License.
16 */
17#pragma once
18
19#include <l4/re/env.h>
20#include <l4/re/util/object_registry>
21#include <l4/re/util/br_manager>
22#include <l4/cxx/ipc_timeout_queue>
23#include <l4/cxx/ref_ptr>
24#include <l4/cxx/exceptions>
25#include <l4/libblock-device/debug.h>
26
27#include <functional>
28
29namespace Block_device { namespace Errand {
30
32extern L4::Ipc_svr::Server_iface *_sif;
33
37typedef std::function<void()> Callback;
38
44 public cxx::Ref_obj
45{
46public:
47 void expired() final
48 {
49 // Recapture the reference pointer from the timeout queue.
50 cxx::Ref_ptr<Poll_errand> p(this, false);
51
52 try
53 {
54 if (_poll())
55 _callback(true);
56 else
57 if (--_retries <= 0)
58 _callback(false);
59 else
60 reschedule();
61 }
62 catch (L4::Runtime_error const &e)
63 {
64 Err().printf("Polling task failed: %s\n", e.str());
65 }
66 }
67
68
69 void reschedule()
70 {
71 // create a place holder reference pointer for the timeout queue
73
74 _sif->add_timeout(p.release(), l4_kip_clock(l4re_kip()) + _interval);
75 }
76
77 // Class can only be instantiated as a reference counting object.
78 template< typename T, typename... Args >
79 friend
80 cxx::Ref_ptr<T> cxx::make_ref_obj(Args &&... args);
81
82private:
83 Poll_errand(int retries, int interval,
84 std::function<bool()> const &poll_func,
85 std::function<void(bool)> const &callback)
86 : _retries(retries),
87 _interval(interval),
88 _poll(poll_func),
89 _callback(callback)
90 {}
91
92 int _retries;
93 int _interval;
94 std::function<bool()> _poll;
95 std::function<void(bool)> _callback;
96};
97
110 public cxx::Ref_obj
111{
112public:
113 void expired() final
114 {
115 // Recapture the reference pointer from the timeout queue.
116 cxx::Ref_ptr<Errand> p(this, false);
117
118 if (_callback)
119 {
120 try
121 {
122 _callback();
123 }
124 catch (L4::Runtime_error const &e)
125 {
126 Err().printf("Asynchronous task failed: %s\n", e.str());
127 }
128 }
129 }
130
131 void reschedule(unsigned interval = 0)
132 {
133 // create a placeholder reference pointer for the timeout queue
134 cxx::Ref_ptr<Errand> p(this);
135
136 _sif->add_timeout(p.release(), l4_kip_clock(l4re_kip()) + interval);
137 }
138
139 // Class can only be instantiated as a reference counting object.
140 template< typename T, typename... Args >
141 friend
142 cxx::Ref_ptr<T> cxx::make_ref_obj(Args &&... args);
143
144private:
145 Errand(Callback const &callback) : _callback(callback) {}
146
147 Callback _callback;
148};
149
150struct Loop_hooks
151: L4::Ipc_svr::Timeout_queue_hooks<Loop_hooks, L4Re::Util::Br_manager>,
153{
154 l4_kernel_clock_t now() { return l4_kip_clock(l4re_kip()); }
155};
156
157using Errand_server = L4Re::Util::Registry_server<Loop_hooks>;
158
164inline void set_server_iface(L4::Ipc_svr::Server_iface *sif) { _sif = sif; }
165
176inline void schedule(Callback const &callback, int interval)
177{
178 cxx::make_ref_obj<Errand>(callback)->reschedule(interval);
179}
180
201inline void poll(int retries, int interval,
202 std::function<bool()> const &poll_func,
203 std::function<void(bool)> const &callback)
204{
205 if (poll_func())
206 callback(true);
207 else
208 cxx::make_ref_obj<Poll_errand>(retries, interval, poll_func,
209 callback)->reschedule();
210}
211
212
213} } // name space
Wrapper for a small task executed asynchronously in the server loop.
Definition errand.h:111
void expired() final
callback function to be called when timeout happened
Definition errand.h:113
Wrapper for a regularly repeated task.
Definition errand.h:45
void expired() final
callback function to be called when timeout happened
Definition errand.h:47
A server loop object which has a Object_registry included.
Interface for server-loop related functions.
Definition ipc_epiface:48
virtual int add_timeout(Timeout *timeout, l4_kernel_clock_t time)=0
Add a timeout to the server internal timeout queue.
Loop hooks mixin for integrating a timeout queue into the server loop.
Callback interface for Timeout_queue.
Exception for an abstract runtime error.
Definition exceptions:140
char const * str() const noexcept override
Return a human readable string for the exception.
Definition exceptions:165
A reference-counting pointer with automatic cleanup.
Definition ref_ptr:82
Environment interface.
Base exceptions.
l4_kernel_info_t const * l4re_kip(void) L4_NOTHROW
Get Kernel Info Page.
Definition env.h:194
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition l4int.h:64
l4_cpu_time_t l4_kip_clock(l4_kernel_info_t const *kip) L4_NOTHROW
Return clock value from the KIP.
Definition kip.h:211
Mix in for LOOP_HOOKS to ignore IPC errors.