MPD: event/Loop.hxx Source File

MPD 0.20.18

Loop.hxx
Go to the documentation of this file.
1 /*
2 * Copyright 2003-2017 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef MPD_EVENT_LOOP_HXX
21 #define MPD_EVENT_LOOP_HXX
22
23 #include "check.h"
24 #include "thread/Id.hxx"
25 #include "Compiler.h"
26
27 #include "PollGroup.hxx"
28 #include "thread/Mutex.hxx"
29 #include "WakeFD.hxx"
30 #include "SocketMonitor.hxx"
31
32 #include <chrono>
33 #include <atomic>
34 #include <list>
35 #include <set>
36
37 class TimeoutMonitor;
38 class IdleMonitor;
39 class DeferredMonitor;
40
41 #include <assert.h>
42
52 class EventLoop final : SocketMonitor
53 {
54 struct TimerRecord {
59 const std::chrono::steady_clock::time_point due;
60
61 TimeoutMonitor &timer;
62
63 constexpr TimerRecord(TimeoutMonitor &_timer,
64 std::chrono::steady_clock::time_point _due)
65 :due(_due), timer(_timer) {}
66
67 bool operator<(const TimerRecord &other) const {
68 return due < other.due;
69 }
70
71 bool IsDue(std::chrono::steady_clock::time_point _now) const {
72 return _now >= due;
73 }
74 };
75
76 WakeFD wake_fd;
77
78 std::multiset<TimerRecord> timers;
79 std::list<IdleMonitor *> idle;
80
81 Mutex mutex;
82 std::list<DeferredMonitor *> deferred;
83
84 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
85
86 std::atomic_bool quit;
87
92 bool again;
93
100 bool busy = true;
101
102 #ifndef NDEBUG
103
107 bool virgin = true;
108 #endif
109
110 PollGroup poll_group;
111 PollResult poll_result;
112
116 ThreadId thread = ThreadId::Null();
117
118 public:
119 EventLoop();
120 ~EventLoop();
121
125 std::chrono::steady_clock::time_point GetTime() const {
126 assert(IsInside());
127
128 return now;
129 }
130
136 void Break();
137
138 bool AddFD(int _fd, unsigned flags, SocketMonitor &m) {
139 assert(thread.IsNull() || thread.IsInside());
140
141 return poll_group.Add(_fd, flags, &m);
142 }
143
144 bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m) {
145 assert(IsInside());
146
147 return poll_group.Modify(_fd, flags, &m);
148 }
149
155 bool Abandon(int fd, SocketMonitor &m);
156
157 bool RemoveFD(int fd, SocketMonitor &m);
158
159 void AddIdle(IdleMonitor &i);
160 void RemoveIdle(IdleMonitor &i);
161
162 void AddTimer(TimeoutMonitor &t,
163 std::chrono::steady_clock::duration d);
164 void CancelTimer(TimeoutMonitor &t);
165
171 void AddDeferred(DeferredMonitor &d);
172
179 void RemoveDeferred(DeferredMonitor &d);
180
185 void Run();
186
187 private:
193 void HandleDeferred();
194
195 virtual bool OnSocketReady(unsigned flags) override;
196
197 public:
198
202 gcc_pure
203 bool IsInside() const noexcept {
204 assert(!thread.IsNull());
205
206 return thread.IsInside();
207 }
208
209 #ifndef NDEBUG
210 gcc_pure
211 bool IsInsideOrVirgin() const noexcept {
212 return virgin || IsInside();
213 }
214 #endif
215
222 gcc_pure
223 bool IsInsideOrNull() const noexcept {
224 return thread.IsNull() || thread.IsInside();
225 }
226 };
227
228 #endif /* MAIN_NOTIFY_H */
check.h
EventLoop::IsInsideOrVirgin
gcc_pure bool IsInsideOrVirgin() const noexcept
Definition: Loop.hxx:211
Id.hxx
TimeoutMonitor
This class monitors a timeout.
Definition: TimeoutMonitor.hxx:37
ThreadId::Null
static constexpr ThreadId Null() noexcept
Definition: Id.hxx:55
EventLoop::EventLoop
EventLoop()
IdleMonitor
An event that runs when the EventLoop has become idle, before waiting for more events.
Definition: IdleMonitor.hxx:35
ThreadId
A low-level identification for a thread.
Definition: Id.hxx:36
EventLoop::GetTime
std::chrono::steady_clock::time_point GetTime() const
A caching wrapper for std::chrono::steady_clock::now().
Definition: Loop.hxx:125
EventLoop::CancelTimer
void CancelTimer(TimeoutMonitor &t)
EventLoop
An event loop that polls for events on file/socket descriptors.
Definition: Loop.hxx:52
EventLoop::Break
void Break()
Stop execution of this EventLoop at the next chance.
EventLoop::AddIdle
void AddIdle(IdleMonitor &i)
EventLoop::RemoveIdle
void RemoveIdle(IdleMonitor &i)
EventLoop::IsInsideOrNull
gcc_pure bool IsInsideOrNull() const noexcept
Like IsInside(), but also returns true if the thread has already ended (or was not started yet)...
Definition: Loop.hxx:223
Mutex
Definition: Mutex.hxx:43
DeferredMonitor
Defer execution of an event into an EventLoop.
Definition: DeferredMonitor.hxx:32
WakeFD.hxx
SocketMonitor.hxx
EventLoop::AddFD
bool AddFD(int _fd, unsigned flags, SocketMonitor &m)
Definition: Loop.hxx:138
SocketMonitor::Abandon
void Abandon()
Somebody has closed the socket.
EventLoop::~EventLoop
~EventLoop()
ThreadId::IsInside
bool IsInside() const noexcept
Check if this thread is the current thread.
Definition: Id.hxx:94
ThreadId::IsNull
gcc_pure bool IsNull() const noexcept
Definition: Id.hxx:64
EventLoop::Run
void Run()
The main function of this class.
Compiler.h
EventLoop::IsInside
gcc_pure bool IsInside() const noexcept
Are we currently running inside this EventLoop&#39;s thread?
Definition: Loop.hxx:203
SocketMonitor
Monitor events on a socket.
Definition: SocketMonitor.hxx:54
Mutex.hxx
PollGroup.hxx
EventLoop::AddTimer
void AddTimer(TimeoutMonitor &t, std::chrono::steady_clock::duration d)
EventLoop::AddDeferred
void AddDeferred(DeferredMonitor &d)
Schedule a call to DeferredMonitor::RunDeferred().
WakeFD
#define WakeFD
Definition: WakeFD.hxx:32
EventLoop::RemoveFD
bool RemoveFD(int fd, SocketMonitor &m)
EventLoop::ModifyFD
bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m)
Definition: Loop.hxx:144
gcc_pure
#define gcc_pure
Definition: Compiler.h:116
EventLoop::RemoveDeferred
void RemoveDeferred(DeferredMonitor &d)
Cancel a pending call to DeferredMonitor::RunDeferred().