Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: base/message_loop/message_pump_win.h

Issue 1954543002: Remove handler from MessagePumpForIO::IOContext. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remove_observers
Patch Set: CR thestig #17 Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/message_loop/message_loop_unittest.cc ('k') | base/message_loop/message_pump_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_
6 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ 6 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_
7 7
8 #include <windows.h> 8 #include <windows.h>
9 9
10 #include <list> 10 #include <list>
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 }; 141 };
142 142
143 //----------------------------------------------------------------------------- 143 //-----------------------------------------------------------------------------
144 // MessagePumpForIO extends MessagePumpWin with methods that are particular to a 144 // MessagePumpForIO extends MessagePumpWin with methods that are particular to a
145 // MessageLoop instantiated with TYPE_IO. This version of MessagePump does not 145 // MessageLoop instantiated with TYPE_IO. This version of MessagePump does not
146 // deal with Windows mesagges, and instead has a Run loop based on Completion 146 // deal with Windows mesagges, and instead has a Run loop based on Completion
147 // Ports so it is better suited for IO operations. 147 // Ports so it is better suited for IO operations.
148 // 148 //
149 class BASE_EXPORT MessagePumpForIO : public MessagePumpWin { 149 class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
150 public: 150 public:
151 struct IOContext; 151 struct BASE_EXPORT IOContext {
152 IOContext();
153 OVERLAPPED overlapped;
154 };
152 155
153 // Clients interested in receiving OS notifications when asynchronous IO 156 // Clients interested in receiving OS notifications when asynchronous IO
154 // operations complete should implement this interface and register themselves 157 // operations complete should implement this interface and register themselves
155 // with the message pump. 158 // with the message pump.
156 // 159 //
157 // Typical use #1: 160 // Typical use #1:
158 // // Use only when there are no user's buffers involved on the actual IO,
159 // // so that all the cleanup can be done by the message pump.
160 // class MyFile : public IOHandler { 161 // class MyFile : public IOHandler {
161 // MyFile() { 162 // MyFile() {
162 // ... 163 // ...
163 // context_ = new IOContext;
164 // context_->handler = this;
165 // message_pump->RegisterIOHandler(file_, this);
166 // }
167 // ~MyFile() {
168 // if (pending_) {
169 // // By setting the handler to NULL, we're asking for this context
170 // // to be deleted when received, without calling back to us.
171 // context_->handler = NULL;
172 // } else {
173 // delete context_;
174 // }
175 // }
176 // virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered,
177 // DWORD error) {
178 // pending_ = false;
179 // }
180 // void DoSomeIo() {
181 // ...
182 // // The only buffer required for this operation is the overlapped
183 // // structure.
184 // ConnectNamedPipe(file_, &context_->overlapped);
185 // pending_ = true;
186 // }
187 // bool pending_;
188 // IOContext* context_;
189 // HANDLE file_;
190 // };
191 //
192 // Typical use #2:
193 // class MyFile : public IOHandler {
194 // MyFile() {
195 // ...
196 // message_pump->RegisterIOHandler(file_, this); 164 // message_pump->RegisterIOHandler(file_, this);
197 // } 165 // }
198 // // Plus some code to make sure that this destructor is not called 166 // // Plus some code to make sure that this destructor is not called
199 // // while there are pending IO operations. 167 // // while there are pending IO operations.
200 // ~MyFile() { 168 // ~MyFile() {
201 // } 169 // }
202 // virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered, 170 // virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered,
203 // DWORD error) { 171 // DWORD error) {
204 // ... 172 // ...
205 // delete context; 173 // delete context;
206 // } 174 // }
207 // void DoSomeIo() { 175 // void DoSomeIo() {
208 // ... 176 // ...
209 // IOContext* context = new IOContext; 177 // IOContext* context = new IOContext;
210 // // This is not used for anything. It just prevents the context from 178 // ReadFile(file_, buffer, num_bytes, &read, &context);
211 // // being considered "abandoned".
212 // context->handler = this;
213 // ReadFile(file_, buffer, num_bytes, &read, &context->overlapped);
214 // } 179 // }
215 // HANDLE file_; 180 // HANDLE file_;
216 // }; 181 // };
217 // 182 //
218 // Typical use #3: 183 // Typical use #2:
219 // Same as the previous example, except that in order to deal with the 184 // Same as the previous example, except that in order to deal with the
220 // requirement stated for the destructor, the class calls WaitForIOCompletion 185 // requirement stated for the destructor, the class calls WaitForIOCompletion
221 // from the destructor to block until all IO finishes. 186 // from the destructor to block until all IO finishes.
222 // ~MyFile() { 187 // ~MyFile() {
223 // while(pending_) 188 // while(pending_)
224 // message_pump->WaitForIOCompletion(INFINITE, this); 189 // message_pump->WaitForIOCompletion(INFINITE, this);
225 // } 190 // }
226 // 191 //
227 class IOHandler { 192 class IOHandler {
228 public: 193 public:
229 virtual ~IOHandler() {} 194 virtual ~IOHandler() {}
230 // This will be called once the pending IO operation associated with 195 // This will be called once the pending IO operation associated with
231 // |context| completes. |error| is the Win32 error code of the IO operation 196 // |context| completes. |error| is the Win32 error code of the IO operation
232 // (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero 197 // (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero
233 // on error. 198 // on error.
234 virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered, 199 virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered,
235 DWORD error) = 0; 200 DWORD error) = 0;
236 }; 201 };
237 202
238 // The extended context that should be used as the base structure on every
239 // overlapped IO operation. |handler| must be set to the registered IOHandler
240 // for the given file when the operation is started, and it can be set to NULL
241 // before the operation completes to indicate that the handler should not be
242 // called anymore, and instead, the IOContext should be deleted when the OS
243 // notifies the completion of this operation. Please remember that any buffers
244 // involved with an IO operation should be around until the callback is
245 // received, so this technique can only be used for IO that do not involve
246 // additional buffers (other than the overlapped structure itself).
247 struct IOContext {
248 OVERLAPPED overlapped;
249 IOHandler* handler;
250 };
251
252 MessagePumpForIO(); 203 MessagePumpForIO();
253 ~MessagePumpForIO() override; 204 ~MessagePumpForIO() override;
254 205
255 // MessagePump methods: 206 // MessagePump methods:
256 void ScheduleWork() override; 207 void ScheduleWork() override;
257 void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; 208 void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
258 209
259 // Register the handler to be used when asynchronous IO for the given file 210 // Register the handler to be used when asynchronous IO for the given file
260 // completes. The registration persists as long as |file_handle| is valid, so 211 // completes. The registration persists as long as |file_handle| is valid, so
261 // |handler| must be valid as long as there is pending IO for the given file. 212 // |handler| must be valid as long as there is pending IO for the given file.
(...skipping 15 matching lines...) Expand all
277 // External use of this method should be reserved for the rare case when the 228 // External use of this method should be reserved for the rare case when the
278 // caller is willing to allow pausing regular task dispatching on this thread. 229 // caller is willing to allow pausing regular task dispatching on this thread.
279 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); 230 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
280 231
281 private: 232 private:
282 struct IOItem { 233 struct IOItem {
283 IOHandler* handler; 234 IOHandler* handler;
284 IOContext* context; 235 IOContext* context;
285 DWORD bytes_transfered; 236 DWORD bytes_transfered;
286 DWORD error; 237 DWORD error;
287
288 // In some cases |context| can be a non-pointer value casted to a pointer.
289 // |has_valid_io_context| is true if |context| is a valid IOContext
290 // pointer, and false otherwise.
291 bool has_valid_io_context;
292 }; 238 };
293 239
294 void DoRunLoop() override; 240 void DoRunLoop() override;
295 void WaitForWork(); 241 void WaitForWork();
296 bool MatchCompletedIOItem(IOHandler* filter, IOItem* item); 242 bool MatchCompletedIOItem(IOHandler* filter, IOItem* item);
297 bool GetIOItem(DWORD timeout, IOItem* item); 243 bool GetIOItem(DWORD timeout, IOItem* item);
298 bool ProcessInternalIOItem(const IOItem& item); 244 bool ProcessInternalIOItem(const IOItem& item);
299 245
300 // Converts an IOHandler pointer to a completion port key.
301 // |has_valid_io_context| specifies whether completion packets posted to
302 // |handler| will have valid OVERLAPPED pointers.
303 static ULONG_PTR HandlerToKey(IOHandler* handler, bool has_valid_io_context);
304
305 // Converts a completion port key to an IOHandler pointer.
306 static IOHandler* KeyToHandler(ULONG_PTR key, bool* has_valid_io_context);
307
308 // The completion port associated with this thread. 246 // The completion port associated with this thread.
309 win::ScopedHandle port_; 247 win::ScopedHandle port_;
310 // This list will be empty almost always. It stores IO completions that have 248 // This list will be empty almost always. It stores IO completions that have
311 // not been delivered yet because somebody was doing cleanup. 249 // not been delivered yet because somebody was doing cleanup.
312 std::list<IOItem> completed_io_; 250 std::list<IOItem> completed_io_;
313 }; 251 };
314 252
315 } // namespace base 253 } // namespace base
316 254
317 #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ 255 #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_
OLDNEW
« no previous file with comments | « base/message_loop/message_loop_unittest.cc ('k') | base/message_loop/message_pump_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698