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

Side by Side Diff: base/message_pump_win.h

Issue 16020005: Fixed the racy code around the message-only window in base::MessagePumpForUI on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 7 years, 6 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 | Annotate | Revision Log
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_PUMP_WIN_H_ 5 #ifndef BASE_MESSAGE_PUMP_WIN_H_
6 #define BASE_MESSAGE_PUMP_WIN_H_ 6 #define BASE_MESSAGE_PUMP_WIN_H_
7 7
8 #include <windows.h> 8 #include <windows.h>
9 9
10 #include <list> 10 #include <list>
11 11
12 #include "base/base_export.h" 12 #include "base/base_export.h"
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_pump.h" 15 #include "base/message_pump.h"
16 #include "base/message_pump_dispatcher.h" 16 #include "base/message_pump_dispatcher.h"
17 #include "base/message_pump_observer.h" 17 #include "base/message_pump_observer.h"
18 #include "base/observer_list.h" 18 #include "base/observer_list.h"
19 #include "base/time.h" 19 #include "base/time.h"
20 #include "base/win/message_window.h"
20 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
21 22
22 namespace base { 23 namespace base {
23 24
24 // MessagePumpWin serves as the base for specialized versions of the MessagePump 25 // MessagePumpWin serves as the base for specialized versions of the MessagePump
25 // for Windows. It provides basic functionality like handling of observers and 26 // for Windows. It provides basic functionality like handling of observers and
26 // controlling the lifetime of the message pump. 27 // controlling the lifetime of the message pump.
27 class BASE_EXPORT MessagePumpWin : public MessagePump { 28 class BASE_EXPORT MessagePumpWin : public MessagePump {
28 public: 29 public:
29 MessagePumpWin() : have_work_(0), state_(NULL) {} 30 MessagePumpWin();
30 virtual ~MessagePumpWin() {} 31 virtual ~MessagePumpWin() {}
31 32
32 // Add an Observer, which will start receiving notifications immediately. 33 // Add an Observer, which will start receiving notifications immediately.
33 void AddObserver(MessagePumpObserver* observer); 34 void AddObserver(MessagePumpObserver* observer);
34 35
35 // Remove an Observer. It is safe to call this method while an Observer is 36 // Remove an Observer. It is safe to call this method while an Observer is
36 // receiving a notification callback. 37 // receiving a notification callback.
37 void RemoveObserver(MessagePumpObserver* observer); 38 void RemoveObserver(MessagePumpObserver* observer);
38 39
39 // Give a chance to code processing additional messages to notify the 40 // Give a chance to code processing additional messages to notify the
(...skipping 21 matching lines...) Expand all
61 }; 62 };
62 63
63 virtual void DoRunLoop() = 0; 64 virtual void DoRunLoop() = 0;
64 int GetCurrentDelay() const; 65 int GetCurrentDelay() const;
65 66
66 ObserverList<MessagePumpObserver> observers_; 67 ObserverList<MessagePumpObserver> observers_;
67 68
68 // The time at which delayed work should run. 69 // The time at which delayed work should run.
69 TimeTicks delayed_work_time_; 70 TimeTicks delayed_work_time_;
70 71
71 // A boolean value used to indicate if there is a kMsgDoWork message pending 72 // Used to indicate if there is a kMsgDoWork message pending in the Windows
72 // in the Windows Message queue. There is at most one such message, and it 73 // Message queue. There is at most one such message, and it can drive
73 // can drive execution of tasks when a native message pump is running. 74 // execution of tasks when a native message pump is running.
74 LONG have_work_; 75 LONG pump_state_;
75 76
76 // State for the current invocation of Run. 77 // State for the current invocation of Run.
77 RunState* state_; 78 RunState* state_;
78 }; 79 };
79 80
80 //----------------------------------------------------------------------------- 81 //-----------------------------------------------------------------------------
81 // MessagePumpForUI extends MessagePumpWin with methods that are particular to a 82 // MessagePumpForUI extends MessagePumpWin with methods that are particular to a
82 // MessageLoop instantiated with TYPE_UI. 83 // MessageLoop instantiated with TYPE_UI.
83 // 84 //
84 // MessagePumpForUI implements a "traditional" Windows message pump. It contains 85 // MessagePumpForUI implements a "traditional" Windows message pump. It contains
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // kMsgHaveWork messages. As a result, care is taken to do some peeking in 119 // kMsgHaveWork messages. As a result, care is taken to do some peeking in
119 // between the posting of each kMsgHaveWork message (i.e., after kMsgHaveWork 120 // between the posting of each kMsgHaveWork message (i.e., after kMsgHaveWork
120 // is peeked, and before a replacement kMsgHaveWork is posted). 121 // is peeked, and before a replacement kMsgHaveWork is posted).
121 // 122 //
122 // NOTE: Although it may seem odd that messages are used to start and stop this 123 // NOTE: Although it may seem odd that messages are used to start and stop this
123 // flow (as opposed to signaling objects, etc.), it should be understood that 124 // flow (as opposed to signaling objects, etc.), it should be understood that
124 // the native message pump will *only* respond to messages. As a result, it is 125 // the native message pump will *only* respond to messages. As a result, it is
125 // an excellent choice. It is also helpful that the starter messages that are 126 // an excellent choice. It is also helpful that the starter messages that are
126 // placed in the queue when new task arrive also awakens DoRunLoop. 127 // placed in the queue when new task arrive also awakens DoRunLoop.
127 // 128 //
128 class BASE_EXPORT MessagePumpForUI : public MessagePumpWin { 129 class BASE_EXPORT MessagePumpForUI
130 : public MessagePumpWin,
131 public win::MessageWindow::Delegate {
129 public: 132 public:
130 // A MessageFilter implements the common Peek/Translate/Dispatch code to deal 133 // A MessageFilter implements the common Peek/Translate/Dispatch code to deal
131 // with windows messages. 134 // with windows messages.
132 // This abstraction is used to inject TSF message peeking. See 135 // This abstraction is used to inject TSF message peeking. See
133 // TextServicesMessageFilter. 136 // TextServicesMessageFilter.
134 class BASE_EXPORT MessageFilter { 137 class BASE_EXPORT MessageFilter {
135 public: 138 public:
136 virtual ~MessageFilter() {} 139 virtual ~MessageFilter() {}
137 // Implements the functionality exposed by the OS through PeekMessage. 140 // Implements the functionality exposed by the OS through PeekMessage.
138 virtual BOOL DoPeekMessage(MSG* msg, 141 virtual BOOL DoPeekMessage(MSG* msg,
(...skipping 20 matching lines...) Expand all
159 162
160 MessagePumpForUI(); 163 MessagePumpForUI();
161 virtual ~MessagePumpForUI(); 164 virtual ~MessagePumpForUI();
162 165
163 // Sets a new MessageFilter. MessagePumpForUI takes ownership of 166 // Sets a new MessageFilter. MessagePumpForUI takes ownership of
164 // |message_filter|. When SetMessageFilter is called, old MessageFilter is 167 // |message_filter|. When SetMessageFilter is called, old MessageFilter is
165 // deleted. 168 // deleted.
166 void SetMessageFilter(scoped_ptr<MessageFilter> message_filter); 169 void SetMessageFilter(scoped_ptr<MessageFilter> message_filter);
167 170
168 // MessagePump methods: 171 // MessagePump methods:
169 virtual void ScheduleWork(); 172 virtual void ScheduleWork() OVERRIDE;
170 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time); 173 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
174 virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
171 175
172 // Applications can call this to encourage us to process all pending WM_PAINT 176 // Applications can call this to encourage us to process all pending WM_PAINT
173 // messages. This method will process all paint messages the Windows Message 177 // messages. This method will process all paint messages the Windows Message
174 // queue can provide, up to some fixed number (to avoid any infinite loops). 178 // queue can provide, up to some fixed number (to avoid any infinite loops).
175 void PumpOutPendingPaintMessages(); 179 void PumpOutPendingPaintMessages();
176 180
177 private: 181 private:
178 static LRESULT CALLBACK WndProcThunk(HWND window_handle, 182 // win::MessageWindow::Delegate interface.
179 UINT message, 183 virtual bool HandleMessage(HWND hwnd,
180 WPARAM wparam, 184 UINT message,
181 LPARAM lparam); 185 WPARAM wparam,
186 LPARAM lparam,
187 LRESULT* result) OVERRIDE;
188
182 virtual void DoRunLoop(); 189 virtual void DoRunLoop();
183 void InitMessageWnd();
184 void WaitForWork(); 190 void WaitForWork();
185 void HandleWorkMessage(); 191 void HandleWorkMessage();
186 void HandleTimerMessage(); 192 void HandleTimerMessage();
187 bool ProcessNextWindowsMessage(); 193 bool ProcessNextWindowsMessage();
188 bool ProcessMessageHelper(const MSG& msg); 194 bool ProcessMessageHelper(const MSG& msg);
189 bool ProcessPumpReplacementMessage(); 195 bool ProcessPumpReplacementMessage();
190 196
191 // Instance of the module containing the window procedure. 197 scoped_ptr<MessageFilter> message_filter_;
192 HMODULE instance_; 198
199 // Used to post an APC to the thread running the message pump.
200 win::ScopedHandle thread_;
193 201
194 // A hidden message-only window. 202 // A hidden message-only window.
195 HWND message_hwnd_; 203 scoped_ptr<win::MessageWindow> window_;
196
197 scoped_ptr<MessageFilter> message_filter_;
198 }; 204 };
199 205
200 //----------------------------------------------------------------------------- 206 //-----------------------------------------------------------------------------
201 // MessagePumpForIO extends MessagePumpWin with methods that are particular to a 207 // MessagePumpForIO extends MessagePumpWin with methods that are particular to a
202 // MessageLoop instantiated with TYPE_IO. This version of MessagePump does not 208 // MessageLoop instantiated with TYPE_IO. This version of MessagePump does not
203 // deal with Windows mesagges, and instead has a Run loop based on Completion 209 // deal with Windows mesagges, and instead has a Run loop based on Completion
204 // Ports so it is better suited for IO operations. 210 // Ports so it is better suited for IO operations.
205 // 211 //
206 class BASE_EXPORT MessagePumpForIO : public MessagePumpWin { 212 class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
207 public: 213 public:
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // This list will be empty almost always. It stores IO completions that have 393 // This list will be empty almost always. It stores IO completions that have
388 // not been delivered yet because somebody was doing cleanup. 394 // not been delivered yet because somebody was doing cleanup.
389 std::list<IOItem> completed_io_; 395 std::list<IOItem> completed_io_;
390 396
391 ObserverList<IOObserver> io_observers_; 397 ObserverList<IOObserver> io_observers_;
392 }; 398 };
393 399
394 } // namespace base 400 } // namespace base
395 401
396 #endif // BASE_MESSAGE_PUMP_WIN_H_ 402 #endif // BASE_MESSAGE_PUMP_WIN_H_
OLDNEW
« no previous file with comments | « base/message_pump.h ('k') | base/message_pump_win.cc » ('j') | base/message_pump_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698