@@ -96,7 +96,19 @@ class MultiSocketMonitor : IdleMonitor, TimeoutMonitor
96
96
97
97
friend class SingleFD ;
98
98
99
- bool ready, refresh;
99
+ /* *
100
+ * DispatchSockets() should be called.
101
+ */
102
+ bool ready = false ;
103
+
104
+ /* *
105
+ * PrepareSockets() should be called.
106
+ *
107
+ * Note that this doesn't need to be initialized by the
108
+ * constructor; this class is activated with the first
109
+ * InvalidateSockets() call, which initializes this flag.
110
+ */
111
+ bool refresh;
100
112
101
113
std::forward_list<SingleFD> fds;
102
114
@@ -107,11 +119,26 @@ public:
107
119
static constexpr unsigned HANGUP = SocketMonitor::HANGUP;
108
120
109
121
MultiSocketMonitor (EventLoop &_loop);
110
- ~MultiSocketMonitor ();
111
122
112
123
using IdleMonitor::GetEventLoop;
113
124
114
- public:
125
+ /* *
126
+ * Clear the socket list and disable all #EventLoop
127
+ * registrations. Run this in the #EventLoop thread before
128
+ * destroying this object.
129
+ *
130
+ * Later, this object can be reused and reactivated by calling
131
+ * InvalidateSockets().
132
+ *
133
+ * Note that this class doesn't have a destructor which calls
134
+ * this method, because this would be racy and thus pointless:
135
+ * at the time ~MultiSocketMonitor() is called, our virtual
136
+ * methods have been morphed to be pure again, and in the
137
+ * meantime the #EventLoop thread could invoke those pure
138
+ * methods.
139
+ */
140
+ void Reset ();
141
+
115
142
/* *
116
143
* Invalidate the socket list. A call to PrepareSockets() is
117
144
* scheduled which will then update the list.
@@ -121,12 +148,19 @@ public:
121
148
IdleMonitor::Schedule ();
122
149
}
123
150
151
+ /* *
152
+ * Add one socket to the list of monitored sockets.
153
+ *
154
+ * May only be called from PrepareSockets().
155
+ */
124
156
void AddSocket (int fd, unsigned events) {
125
157
fds.emplace_front (*this , fd, events);
126
158
}
127
159
128
160
/* *
129
161
* Remove all sockets.
162
+ *
163
+ * May only be called from PrepareSockets().
130
164
*/
131
165
void ClearSocketList ();
132
166
@@ -135,6 +169,8 @@ public:
135
169
* each one; its return value is the events bit mask. A
136
170
* return value of 0 means the socket will be removed from the
137
171
* list.
172
+ *
173
+ * May only be called from PrepareSockets().
138
174
*/
139
175
template <typename E>
140
176
void UpdateSocketList (E &&e) {
@@ -157,15 +193,26 @@ public:
157
193
/* *
158
194
* Replace the socket list with the given file descriptors.
159
195
* The given pollfd array will be modified by this method.
196
+ *
197
+ * May only be called from PrepareSockets().
160
198
*/
161
199
void ReplaceSocketList (pollfd *pfds, unsigned n);
162
200
#endif
163
201
164
202
protected:
165
203
/* *
204
+ * Override this method and update the socket registrations.
205
+ * To do that, call AddSocket(), ClearSocketList(),
206
+ * UpdateSocketList() and ReplaceSocketList().
207
+ *
166
208
* @return timeout or a negative value for no timeout
167
209
*/
168
210
virtual std::chrono::steady_clock::duration PrepareSockets () = 0;
211
+
212
+ /* *
213
+ * At least one socket is ready or the timeout has expired.
214
+ * This method should be used to perform I/O.
215
+ */
169
216
virtual void DispatchSockets () = 0;
170
217
171
218
private:
0 commit comments