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

Unified Diff: base/message_loop/message_pump_win.cc

Issue 15709015: Make sure that the UI window created by base::MessagePumpForUI is destoyed on the same thread (Wind… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_loop/message_pump_win.h ('k') | tools/valgrind/tsan/suppressions.txt » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/message_loop/message_pump_win.cc
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index 36a321092ff21c2f6be12d7fd36f2653e5ddd025..23654946e8555b4d71a9886b4fb432044312d5ea 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -67,6 +67,10 @@ void MessagePumpWin::RunWithDispatcher(
state_ = previous_state;
}
+void MessagePumpWin::Run(Delegate* delegate) {
+ RunWithDispatcher(delegate, NULL);
+}
+
void MessagePumpWin::Quit() {
DCHECK(state_);
state_->should_quit = true;
@@ -103,20 +107,32 @@ MessagePumpForUI::MessagePumpForUI()
}
MessagePumpForUI::~MessagePumpForUI() {
- DestroyWindow(message_hwnd_);
- UnregisterClass(MAKEINTATOM(atom_),
- GetModuleFromAddress(&WndProcThunk));
+ DCHECK(!atom_);
+ DCHECK(!message_hwnd_);
}
void MessagePumpForUI::ScheduleWork() {
if (InterlockedExchange(&have_work_, 1))
return; // Someone else continued the pumping.
- // Make sure the MessagePump does some work for us.
- BOOL ret = PostMessage(message_hwnd_, kMsgHaveWork,
- reinterpret_cast<WPARAM>(this), 0);
- if (ret)
- return; // There was room in the Window Message queue.
+ // If the attempt to acquire the lock fails, the message loop is shutting down
+ // and the message window is about to be destroyed as well.
+ if (!message_hwnd_lock_.Try())
+ return;
+
+ {
+ base::AutoLock lock(message_hwnd_lock_, base::AutoLock::AlreadyAcquired());
+
+ // Do nothing if the window has been destroyed already.
+ if (!message_hwnd_)
+ return;
+
+ // Make sure the MessagePump does some work for us.
+ if (PostMessage(message_hwnd_, kMsgHaveWork,
+ reinterpret_cast<WPARAM>(this), 0)) {
+ return;
+ }
+ }
// We have failed to insert a have-work message, so there is a chance that we
// will starve tasks/timers while sitting in a nested message loop. Nested
@@ -172,6 +188,24 @@ void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
MESSAGE_LOOP_PROBLEM_MAX);
}
+void MessagePumpForUI::Shutdown() {
+ HWND message_hwnd;
+ {
+ base::AutoLock lock(message_hwnd_lock_);
+
+ // Let ScheduleWork() know that the window has been destoyed.
+ message_hwnd = message_hwnd_;
+ message_hwnd_ = NULL;
+ }
+
+ // Destoy the window and its class. The destructor checks whether
+ // |message_hwnd_| and |atom_| are destroyed, so the variables should be
+ // cleared here.
+ DestroyWindow(message_hwnd);
+ UnregisterClass(MAKEINTATOM(atom_), GetModuleFromAddress(&WndProcThunk));
+ atom_ = 0;
+}
+
void MessagePumpForUI::PumpOutPendingPaintMessages() {
// If we are being called outside of the context of Run, then don't try to do
// any work.
@@ -478,7 +512,7 @@ void MessagePumpForIO::ScheduleWork() {
return; // Post worked perfectly.
// See comment in MessagePumpForUI::ScheduleWork() for this error recovery.
- InterlockedExchange(&have_work_, 0); // Clarify that we didn't succeed.
+ InterlockedExchange(&have_work_, 0);
UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", COMPLETION_POST_ERROR,
MESSAGE_LOOP_PROBLEM_MAX);
}
@@ -490,6 +524,9 @@ void MessagePumpForIO::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
delayed_work_time_ = delayed_work_time;
}
+void MessagePumpForIO::Shutdown() {
+}
+
void MessagePumpForIO::RegisterIOHandler(HANDLE file_handle,
IOHandler* handler) {
ULONG_PTR key = HandlerToKey(handler, true);
« no previous file with comments | « base/message_loop/message_pump_win.h ('k') | tools/valgrind/tsan/suppressions.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698