EventLoop.h
1/*
2 * Copyright (C) 2006-2013 Marc Boris Duerner
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * As a special exception, you may use this file as part of a free
10 * software library without restriction. Specifically, if other files
11 * instantiate templates or use macros or inline functions from this
12 * file, or you compile this file and link it with other files to
13 * produce an executable, this file does not by itself cause the
14 * resulting executable to be covered by the GNU General Public
15 * License. This exception does not however invalidate any other
16 * reasons why the executable file might be covered by the GNU Library
17 * General Public License.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#ifndef PT_SYSTEM_EVENTLOOP_H
30#define PT_SYSTEM_EVENTLOOP_H
31
32#include <Pt/Event.h>
33#include <Pt/Signal.h>
34#include <Pt/Timespan.h>
35#include <Pt/Allocator.h>
36#include <Pt/Connectable.h>
37#include <Pt/System/Api.h>
38#include <Pt/System/Mutex.h>
39#include <Pt/System/Timer.h>
40#include <Pt/System/EventSink.h>
41#include <map>
42#include <deque>
43
44#if __cplusplus >= 202002L
45#include <Pt/Coroutine.h>
46#include <Pt/System/Selectable.h>
47#endif
48
49namespace Pt {
50
51namespace System {
52
53class Timer;
54class Selectable;
55class Selector;
56
57#if __cplusplus >= 202002L
58class AsyncYield;
59#endif
60
81class PT_SYSTEM_API EventLoop : public Connectable
82 , public EventSink
83{
84 friend class Selectable;
85 friend class Timer;
86
87 public:
90 static const std::size_t WaitInfinite = static_cast<const std::size_t>(-1);
91
94 static const std::size_t WaitMax = WaitInfinite - 1;
95
98 virtual ~EventLoop();
99
102 void run();
103
106 void exit();
107
111
115 { return _event; }
116
120 { return _exited; }
121
122#if __cplusplus >= 202002L
126 AsyncYield yieldAsync();
127#endif
128
136 void post(Selectable& s)
137 {
138 onReady(s);
139 wake();
140 }
141
143 void setReady(Selectable& s)
144 {
145 onReady(s);
146 }
147
149 virtual Selector& selector() = 0;
150
151 protected:
153 EventLoop();
154
156 virtual void onRun() = 0;
157
159 virtual void onExit() = 0;
160
162 virtual void onCommitEvent(const Event& ev) = 0;
163
165 virtual void onQueueEvent(const Event& ev) = 0;
166
168 virtual void onWake() = 0;
169
171 virtual void onProcessEvents() = 0;
172
174 virtual void onAttachTimer(Timer& timer) = 0;
175
177 virtual void onDetachTimer(Timer& timer) = 0;
178
180 virtual void onAttachSelectable(Selectable&) = 0;
181
183 virtual void onDetachSelectable(Selectable&) = 0;
184
186 virtual void onReady(Selectable&) = 0;
187
189 virtual void onCancel(Selectable&) = 0;
190
191 private:
192 Signal<> _exited;
194};
195
197class PT_SYSTEM_API EventQueue
198{
199 public:
200 EventQueue();
201
202 EventQueue(Allocator& a);
203
204 virtual ~EventQueue();
205
206 Allocator& allocator()
207 { return *_usedalloc; }
208
209 void exit();
210
211 void pushEvent(const Event& event);
212
213 bool processEvents(Signal<const Event&>& eventSignal);
214
215 private:
216 Mutex _mutex;
217 Allocator _allocator;
218 Allocator* _usedalloc;
219 std::deque<Event*> _eventQueue;
220 bool _exited;
221};
222
224class PT_SYSTEM_API TimerQueue
225{
226 typedef std::multimap<Timespan, Timer*> TimerMap;
227
228 public:
229 TimerQueue();
230
231 virtual ~TimerQueue();
232
233 void addTimer(Timer& timer);
234
235 void removeTimer(Timer& timer);
236
237 std::size_t processTimers();
238
239 private:
240 TimerMap _timers;
241};
242
243#if __cplusplus >= 202002L
244
252class PT_SYSTEM_API AsyncYield : public Pt::Awaiter
253 , private Pt::System::Selectable
254{
255 public:
256 explicit AsyncYield(EventLoop& loop)
257 {
258 this->setActive(loop);
259 }
260
261 virtual ~AsyncYield()
262 {
264 }
265
266 void await_resume() noexcept
267 {}
268
269 protected:
270 void onBegin() override
271 {
272 this->post();
273 }
274
275 void cancel() override
276 {
278 }
279
280 void onCancel() override
281 {
282 _handle = nullptr;
283 }
284
286 {}
287
289 {}
290
291 bool onRun() override
292 {
293 this->setReady();
294 return true;
295 }
296};
297
299{
300 return AsyncYield(*this);
301}
302
303#endif // __cplusplus >= 202002L
304
305} // namespace System
306
307} // namespace Pt
308
309#endif // PT_SYSTEM_EVENTLOOP_H
Allocator interface.
Definition Allocator.h:82
Provides the base class for I/O-driven co_await-able operations.
Definition Coroutine.h:126
void setReady()
Resumes the waiting coroutine.
Definition Coroutine.h:162
Connectable()
Default constructor.
Base class for typed events.
Definition Event.h:66
Multicast Signal to call multiple slots.
Definition Signal.h:190
Awaitable that schedules a resume in the EventLoop.
Definition EventLoop.h:254
void onDetach(Pt::System::EventLoop &) override
Detached from loop.
Definition EventLoop.h:288
void cancel() override
Cancels the pending operation.
Definition EventLoop.h:275
void onBegin() override
Starts the asynchronous operation.
Definition EventLoop.h:270
void onAttach(Pt::System::EventLoop &) override
Attached to loop.
Definition EventLoop.h:285
bool onRun() override
Check if ready and run.
Definition EventLoop.h:291
void onCancel() override
Aborts the in-flight operation.
Definition EventLoop.h:280
Event loop of a thread or process.
Definition EventLoop.h:83
void run()
Starts the loop.
Signal< const Event & > & eventReceived()
Reports all events.
Definition EventLoop.h:114
AsyncYield yieldAsync()
Pauses a coroutine and delegates execution back to the loop.
Definition EventLoop.h:298
virtual void onQueueEvent(const Event &ev)=0
Only queues an event.
void exit()
Stops the loop.
virtual void onCommitEvent(const Event &ev)=0
Queues an event and triggers event processing.
void setReady(Selectable &s)
Sets the Selectable as ready without waking the loop.
Definition EventLoop.h:143
void post(Selectable &s)
Posts the loop to run a selectable.
Definition EventLoop.h:136
virtual void onWake()=0
Triggers event processing.
virtual ~EventLoop()
Destructor.
void processEvents()
Process all queued events.
Signal & exited()
Emited when the eventloop is exited.
Definition EventLoop.h:119
EventSink()
Default Constructor.
void wake()
Triggers event processing.
Operation that runs through an event loop.
Definition Selectable.h:60
void cancel()
Cancels all operations.
void setActive(EventLoop &parent)
Sets the parent loop, so that operations can be run.
void post()
Posts this selectable to its event loop from any thread.
Interval timeout notifications.
Definition Timer.h:74
System programming
Definition Connection.h:26
Core module.
Definition Allocator.h:33