MPD: event/Loop.hxx Source File

MPD 0.20.15

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 <list>
34 #include <set>
35
36 class TimeoutMonitor;
37 class IdleMonitor;
38 class DeferredMonitor;
39
40 #include <assert.h>
41
51 class EventLoop final : SocketMonitor
52 {
53 struct TimerRecord {
58 const std::chrono::steady_clock::time_point due;
59
60 TimeoutMonitor &timer;
61
62 constexpr TimerRecord(TimeoutMonitor &_timer,
63 std::chrono::steady_clock::time_point _due)
64 :due(_due), timer(_timer) {}
65
66 bool operator<(const TimerRecord &other) const {
67 return due < other.due;
68 }
69
70 bool IsDue(std::chrono::steady_clock::time_point _now) const {
71 return _now >= due;
72 }
73 };
74
75 WakeFD wake_fd;
76
77 std::multiset<TimerRecord> timers;
78 std::list<IdleMonitor *> idle;
79
80 Mutex mutex;
81 std::list<DeferredMonitor *> deferred;
82
83 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
84
85 bool quit = false;
86
91 bool again;
92
99 bool busy = true;
100
101 #ifndef NDEBUG
102
106 bool virgin = true;
107 #endif
108
109 PollGroup poll_group;
110 PollResult poll_result;
111
115 ThreadId thread = ThreadId::Null();
116
117 public:
118 EventLoop();
119 ~EventLoop();
120
124 std::chrono::steady_clock::time_point GetTime() const {
125 assert(IsInside());
126
127 return now;
128 }
129
135 void Break();
136
137 bool AddFD(int _fd, unsigned flags, SocketMonitor &m) {
138 assert(thread.IsNull() || thread.IsInside());
139
140 return poll_group.Add(_fd, flags, &m);
141 }
142
143 bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m) {
144 assert(IsInside());
145
146 return poll_group.Modify(_fd, flags, &m);
147 }
148
154 bool Abandon(int fd, SocketMonitor &m);
155
156 bool RemoveFD(int fd, SocketMonitor &m);
157
158 void AddIdle(IdleMonitor &i);
159 void RemoveIdle(IdleMonitor &i);
160
161 void AddTimer(TimeoutMonitor &t,
162 std::chrono::steady_clock::duration d);
163 void CancelTimer(TimeoutMonitor &t);
164
170 void AddDeferred(DeferredMonitor &d);
171
178 void RemoveDeferred(DeferredMonitor &d);
179
184 void Run();
185
186 private:
192 void HandleDeferred();
193
194 virtual bool OnSocketReady(unsigned flags) override;
195
196 public:
197
201 gcc_pure
202 bool IsInside() const noexcept {
203 assert(!thread.IsNull());
204
205 return thread.IsInside();
206 }
207
208 #ifndef NDEBUG
209 gcc_pure
210 bool IsInsideOrVirgin() const noexcept {
211 return virgin || IsInside();
212 }
213 #endif
214
221 gcc_pure
222 bool IsInsideOrNull() const noexcept {
223 return thread.IsNull() || thread.IsInside();
224 }
225 };
226
227 #endif /* MAIN_NOTIFY_H */
check.h
ThreadId::Null
static gcc_const ThreadId Null() noexcept
Definition: Id.hxx:56
EventLoop::IsInsideOrVirgin
gcc_pure bool IsInsideOrVirgin() const noexcept
Definition: Loop.hxx:210
Id.hxx
TimeoutMonitor
This class monitors a timeout.
Definition: TimeoutMonitor.hxx:37
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:124
EventLoop::CancelTimer
void CancelTimer(TimeoutMonitor &t)
EventLoop
An event loop that polls for events on file/socket descriptors.
Definition: Loop.hxx:51
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:222
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:137
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:66
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:202
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:143
gcc_pure
#define gcc_pure
Definition: Compiler.h:116
EventLoop::RemoveDeferred
void RemoveDeferred(DeferredMonitor &d)
Cancel a pending call to DeferredMonitor::RunDeferred().