MPD: event/MultiSocketMonitor.hxx Source File

MPD 0.20.15

MultiSocketMonitor.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_MULTI_SOCKET_MONITOR_HXX
21 #define MPD_MULTI_SOCKET_MONITOR_HXX
22
23 #include "check.h"
24 #include "IdleMonitor.hxx"
25 #include "TimeoutMonitor.hxx"
26 #include "SocketMonitor.hxx"
27 #include "Compiler.h"
28
29 #include <forward_list>
30 #include <iterator>
31
32 #include <assert.h>
33
34 #ifdef _WIN32
35 /* ERROR is a WIN32 macro that poisons our namespace; this is a kludge
36 to allow us to use it anyway */
37 #ifdef ERROR
38 #undef ERROR
39 #endif
40 #endif
41
42 #ifndef _WIN32
43 struct pollfd;
44 #endif
45
46 class EventLoop;
47
54 class MultiSocketMonitor : IdleMonitor, TimeoutMonitor
55 {
56 class SingleFD final : public SocketMonitor {
57 MultiSocketMonitor &multi;
58
59 unsigned revents;
60
61 public:
62 SingleFD(MultiSocketMonitor &_multi, int _fd, unsigned events)
63 :SocketMonitor(_fd, _multi.GetEventLoop()),
64 multi(_multi), revents(0) {
65 Schedule(events);
66 }
67
68 int GetFD() const {
69 return SocketMonitor::Get();
70 }
71
72 unsigned GetEvents() const {
73 return SocketMonitor::GetScheduledFlags();
74 }
75
76 void SetEvents(unsigned _events) {
77 revents &= _events;
78 SocketMonitor::Schedule(_events);
79 }
80
81 unsigned GetReturnedEvents() const {
82 return revents;
83 }
84
85 void ClearReturnedEvents() {
86 revents = 0;
87 }
88
89 protected:
90 virtual bool OnSocketReady(unsigned flags) override {
91 revents = flags;
92 multi.SetReady();
93 return true;
94 }
95 };
96
97 friend class SingleFD;
98
102 bool ready = false;
103
111 bool refresh;
112
113 std::forward_list<SingleFD> fds;
114
115 public:
116 static constexpr unsigned READ = SocketMonitor::READ;
117 static constexpr unsigned WRITE = SocketMonitor::WRITE;
118 static constexpr unsigned ERROR = SocketMonitor::ERROR;
119 static constexpr unsigned HANGUP = SocketMonitor::HANGUP;
120
121 MultiSocketMonitor(EventLoop &_loop);
122
123 using IdleMonitor::GetEventLoop;
124
140 void Reset();
141
146 void InvalidateSockets() {
147 refresh = true;
148 IdleMonitor::Schedule();
149 }
150
156 void AddSocket(int fd, unsigned events) {
157 fds.emplace_front(*this, fd, events);
158 }
159
165 void ClearSocketList();
166
175 template<typename E>
176 void UpdateSocketList(E &&e) {
177 for (auto prev = fds.before_begin(), end = fds.end(),
178 i = std::next(prev);
179 i != end; i = std::next(prev)) {
180 assert(i->GetEvents() != 0);
181
182 unsigned events = e(i->GetFD());
183 if (events != 0) {
184 i->SetEvents(events);
185 prev = i;
186 } else {
187 fds.erase_after(prev);
188 }
189 }
190 }
191
192 #ifndef _WIN32
193
199 void ReplaceSocketList(pollfd *pfds, unsigned n);
200 #endif
201
202 protected:
210 virtual std::chrono::steady_clock::duration PrepareSockets() = 0;
211
216 virtual void DispatchSockets() = 0;
217
218 private:
219 void SetReady() {
220 ready = true;
221 IdleMonitor::Schedule();
222 }
223
224 void Prepare();
225
226 virtual void OnTimeout() final {
227 SetReady();
228 IdleMonitor::Schedule();
229 }
230
231 virtual void OnIdle() final;
232 };
233
234 #endif
check.h
SocketMonitor::WRITE
static constexpr unsigned WRITE
Definition: SocketMonitor.hxx:65
MultiSocketMonitor::InvalidateSockets
void InvalidateSockets()
Invalidate the socket list.
Definition: MultiSocketMonitor.hxx:146
MultiSocketMonitor::READ
static constexpr unsigned READ
Definition: MultiSocketMonitor.hxx:116
MultiSocketMonitor::AddSocket
void AddSocket(int fd, unsigned events)
Add one socket to the list of monitored sockets.
Definition: MultiSocketMonitor.hxx:156
TimeoutMonitor
This class monitors a timeout.
Definition: TimeoutMonitor.hxx:37
IdleMonitor
An event that runs when the EventLoop has become idle, before waiting for more events.
Definition: IdleMonitor.hxx:35
EventLoop
An event loop that polls for events on file/socket descriptors.
Definition: Loop.hxx:51
MultiSocketMonitor::UpdateSocketList
void UpdateSocketList(E &&e)
Update the known sockets by invoking the given function for each one; its return value is the events ...
Definition: MultiSocketMonitor.hxx:176
SocketMonitor::Schedule
void Schedule(unsigned flags)
MultiSocketMonitor::ClearSocketList
void ClearSocketList()
Remove all sockets.
SocketMonitor::Get
int Get() const
Definition: SocketMonitor.hxx:87
SocketMonitor.hxx
IdleMonitor::GetEventLoop
EventLoop & GetEventLoop() const
Definition: IdleMonitor.hxx:55
MultiSocketMonitor::Reset
void Reset()
Clear the socket list and disable all EventLoop registrations.
MultiSocketMonitor::SingleFD
friend class SingleFD
Definition: MultiSocketMonitor.hxx:97
Compiler.h
MultiSocketMonitor::ReplaceSocketList
void ReplaceSocketList(pollfd *pfds, unsigned n)
Replace the socket list with the given file descriptors.
SocketMonitor::ERROR
static constexpr unsigned ERROR
Definition: SocketMonitor.hxx:66
MultiSocketMonitor::PrepareSockets
virtual std::chrono::steady_clock::duration PrepareSockets()=0
Override this method and update the socket registrations.
TimeoutMonitor.hxx
SocketMonitor
Monitor events on a socket.
Definition: SocketMonitor.hxx:54
SocketMonitor::HANGUP
static constexpr unsigned HANGUP
Definition: SocketMonitor.hxx:67
MultiSocketMonitor::MultiSocketMonitor
MultiSocketMonitor(EventLoop &_loop)
SocketMonitor::READ
static constexpr unsigned READ
Definition: SocketMonitor.hxx:64
MultiSocketMonitor::DispatchSockets
virtual void DispatchSockets()=0
At least one socket is ready or the timeout has expired.
MultiSocketMonitor::WRITE
static constexpr unsigned WRITE
Definition: MultiSocketMonitor.hxx:117
IdleMonitor::Schedule
void Schedule()
MultiSocketMonitor::HANGUP
static constexpr unsigned HANGUP
Definition: MultiSocketMonitor.hxx:119
MultiSocketMonitor
Similar to SocketMonitor, but monitors multiple sockets.
Definition: MultiSocketMonitor.hxx:54
IdleMonitor.hxx
MultiSocketMonitor::ERROR
static constexpr unsigned ERROR
Definition: MultiSocketMonitor.hxx:118
e
int e
Definition: Log.hxx:115
SocketMonitor::GetScheduledFlags
unsigned GetScheduledFlags() const
Definition: SocketMonitor.hxx:108
MultiSocketMonitor::GetEventLoop
EventLoop & GetEventLoop() const
Definition: IdleMonitor.hxx:55