Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Notifiable.hxx
Go to the documentation of this file.
1
34#ifndef _EXECUTOR_NOTIFIABLE_HXX_
35#define _EXECUTOR_NOTIFIABLE_HXX_
36
37#include <functional>
38
39#include "os/OS.hxx"
40#include "utils/Atomic.hxx"
42
45{
46public:
48 virtual void notify() = 0;
49#if OPENMRN_FEATURE_RTOS_FROM_ISR
50 virtual void notify_from_isr()
51 {
52 DIE("Unexpected call to notify_from_isr.");
53 }
54#endif // OPENMRN_FEATURE_RTOS_FROM_ISR
55};
56
61{
62public:
65 {
66 }
67
69 void notify() override
70 {
71 sem_.post();
72 }
73
74#if OPENMRN_FEATURE_RTOS_FROM_ISR
77 void notify_from_isr() OVERRIDE
78 {
79 int woken = 0;
80 sem_.post_from_isr(&woken);
81 }
82#endif // OPENMRN_FEATURE_RTOS_FROM_ISR
83
86 {
87 sem_.wait();
88 }
89
90private:
93
95};
96
99{
100public:
102 void notify() override
103 {
104 }
105
107 static Notifiable* DefaultInstance();
108};
109
112{
113public:
115 void notify() override;
116
118 static Notifiable* DefaultInstance();
119};
120
130{
131public:
132 ProxyNotifiable() : parent_(nullptr)
133 {
134 }
144 {
146 parent_ = parent;
147 return this;
148 }
152 {
153 return !parent_;
154 };
155
156private:
158 void notify() override
159 {
160 Notifiable* p = parent_;
161 HASSERT(p);
162 parent_ = nullptr;
163 p->notify();
164 }
165
169};
170
174class BarrierNotifiable : public Notifiable, protected Atomic
175{
176public:
180 {
181 }
186 {
187 }
188
191
193
201 {
202 notify();
203 }
205 void notify() override;
206
209 bool is_done()
210 {
211 return !count_;
212 }
213
229 {
230 AtomicHolder h(this);
231 HASSERT(!is_done());
232 if (count_ == 1)
233 {
234 count_ = 0;
235 return true;
236 }
237 else
238 {
239 return false;
240 }
241 }
242
243protected:
246 unsigned count_;
249};
250
257{
258 return new BarrierNotifiable(done);
259}
260
274{
275public:
282 : n_(n)
283 {
284 }
285
288 {
289 if (n_)
290 {
291 n_->notify();
292 }
293 }
294
299 {
300 Notifiable* r = n_;
301 n_ = nullptr;
302 return r;
303 }
304
305private:
308};
309
319#define AutoNotify(l) int error_omitted_autonotify_holder_variable[-1]
320
324{
325public:
328 TempNotifiable(std::function<void()> body)
329 : body_(std::move(body))
330 {
331 }
332
335 {
336 body_();
337 delete this;
338 }
339
340private:
342 std::function<void()> body_;
343};
344
345#endif // _EXECUTOR_NOTIFIABLE_HXX_
BarrierNotifiable * NewBarrierNotifiable(Notifiable *done)
Allocates a new barrier notifiable on the heap.
See OSMutexLock in os/OS.hxx.
Definition Atomic.hxx:153
Lightweight locking class for protecting small critical sections.
Definition Atomic.hxx:130
This class sends a notification in its destructor.
Notifiable * Transfer()
Transfers the ownership of the notification; it will NOT be called in the destructor.
Notifiable * n_
Stored notifiable to notify upon destruction.
~AutoNotify()
Destructor. Notifies the stored notifiable.
AutoNotify(Notifiable *n)
Constructor.
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
BarrierNotifiable()
Constructs a barrier notifiable that is done.
void notify() override
Implementation of the barrier semantics.
unsigned count_
How many outstanding notifications we are still waiting for.
Notifiable * done_
Notifiable to call when the barrier reaches zero.
BarrierNotifiable * reset(Notifiable *done)
Resets the barrier. Returns &*this. Asserts that is_done().
BarrierNotifiable(Notifiable *done)
Constructs a barrier notifiable that is live.
void maybe_done()
When there are no more child tasks to add, call maybe_done().
BarrierNotifiable * new_child()
Call this for each child task.
bool abort_if_almost_done()
Checks if there is exactly one outstanding notification left in the barrier.
A Notifiable that will crash whenever called.
void notify() override
Crashes.
static Notifiable * DefaultInstance()
Base class of everything with a virtual destructor.
A Notifiable that doesn't do anything when notified.
void notify() override
Drops notification to the floor.
static Notifiable * DefaultInstance()
An object that can schedule itself on an executor to run.
virtual void notify()=0
Generic callback.
This class provides a counting semaphore API.
Definition OS.hxx:243
void post()
Post (increment) a semaphore.
Definition OS.hxx:260
void wait()
Wait on (decrement) a semaphore.
Definition OS.hxx:279
A class for reliably detecting whether a Notification has happened yet or not.
void notify() override
Implementation of the private Notifiable interface.
Notifiable * parent_
Where to proxy notifications.
Notifiable * NewCallback(Notifiable *parent)
Creates a new callback.
A Notifiable for synchronously waiting for a notification.
void notify() override
Implementation of notification receive.
void wait_for_notification()
Blocks the current thread until the notification is delivered.
OSSem sem_
Semaphore helping the implementation.
SyncNotifiable()
Constructor.
A notifiable class that calls a particular function object once when it is invoked,...
TempNotifiable(std::function< void()> body)
Constructor.
std::function< void()> body_
Function object (callback) to call.
void notify() OVERRIDE
Calls the notification method.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
Definition macros.h:180
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define DIE(MSG)
Unconditionally terminates the current process with a message.
Definition macros.h:143
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171