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

Side by Side Diff: content/browser/browser_message_filter.cc

Issue 6745031: Revert 79470 - Ensure that BrowserMessageFilter isn't used to process a sync message on the UI th... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 9 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #include "content/browser/browser_message_filter.h" 5 #include "content/browser/browser_message_filter.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/process.h" 8 #include "base/process.h"
9 #include "base/process_util.h" 9 #include "base/process_util.h"
10 #include "chrome/browser/metrics/user_metrics.h" 10 #include "chrome/browser/metrics/user_metrics.h"
11 #include "content/common/result_codes.h" 11 #include "content/common/result_codes.h"
12 #include "ipc/ipc_sync_message.h"
13 12
14 BrowserMessageFilter::BrowserMessageFilter() 13 BrowserMessageFilter::BrowserMessageFilter()
15 : channel_(NULL), peer_handle_(base::kNullProcessHandle) { 14 : channel_(NULL), peer_handle_(base::kNullProcessHandle) {
16 } 15 }
17 16
18 BrowserMessageFilter::~BrowserMessageFilter() { 17 BrowserMessageFilter::~BrowserMessageFilter() {
19 base::CloseProcessHandle(peer_handle_); 18 base::CloseProcessHandle(peer_handle_);
20 } 19 }
21 20
22 void BrowserMessageFilter::OnFilterAdded(IPC::Channel* channel) { 21 void BrowserMessageFilter::OnFilterAdded(IPC::Channel* channel) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 void BrowserMessageFilter::OverrideThreadForMessage(const IPC::Message& message, 60 void BrowserMessageFilter::OverrideThreadForMessage(const IPC::Message& message,
62 BrowserThread::ID* thread) { 61 BrowserThread::ID* thread) {
63 } 62 }
64 63
65 bool BrowserMessageFilter::OnMessageReceived(const IPC::Message& message) { 64 bool BrowserMessageFilter::OnMessageReceived(const IPC::Message& message) {
66 BrowserThread::ID thread = BrowserThread::IO; 65 BrowserThread::ID thread = BrowserThread::IO;
67 OverrideThreadForMessage(message, &thread); 66 OverrideThreadForMessage(message, &thread);
68 if (thread == BrowserThread::IO) 67 if (thread == BrowserThread::IO)
69 return DispatchMessage(message); 68 return DispatchMessage(message);
70 69
71 if (thread == BrowserThread::UI && !CheckCanDispatchOnUI(message, this))
72 return true;
73
74 BrowserThread::PostTask( 70 BrowserThread::PostTask(
75 thread, FROM_HERE, 71 thread, FROM_HERE,
76 NewRunnableMethod( 72 NewRunnableMethod(
77 this, &BrowserMessageFilter::DispatchMessage, message)); 73 this, &BrowserMessageFilter::DispatchMessage, message));
78 return true; 74 return true;
79 } 75 }
80 76
81 bool BrowserMessageFilter::DispatchMessage(const IPC::Message& message) { 77 bool BrowserMessageFilter::DispatchMessage(const IPC::Message& message) {
82 bool message_was_ok = true; 78 bool message_was_ok = true;
83 bool rv = OnMessageReceived(message, &message_was_ok); 79 bool rv = OnMessageReceived(message, &message_was_ok);
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) || rv) << 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) || rv) <<
85 "Must handle messages that were dispatched to another thread!"; 81 "Must handle messages that were dispatched to another thread!";
86 if (!message_was_ok) { 82 if (!message_was_ok) {
87 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_BMF")); 83 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_BMF"));
88 BadMessageReceived(); 84 BadMessageReceived();
89 } 85 }
90 86
91 return rv; 87 return rv;
92 } 88 }
93 89
94 void BrowserMessageFilter::BadMessageReceived() { 90 void BrowserMessageFilter::BadMessageReceived() {
95 base::KillProcess(peer_handle(), ResultCodes::KILLED_BAD_MESSAGE, false); 91 base::KillProcess(peer_handle(), ResultCodes::KILLED_BAD_MESSAGE, false);
96 } 92 }
97
98 bool BrowserMessageFilter::CheckCanDispatchOnUI(
99 const IPC::Message& message, IPC::Message::Sender* sender) {
100 #if defined(OS_WIN)
101 // On Windows there's a potential deadlock with sync messsages going in
102 // a circle from browser -> plugin -> renderer -> browser.
103 // On Linux we can avoid this by avoiding sync messages from browser->plugin.
104 // On Mac we avoid this by not supporting windowed plugins.
105 if (message.is_sync() && !message.is_caller_pumping_messages()) {
106 // NOTE: IF YOU HIT THIS ASSERT, THE SOLUTION IS ALMOST NEVER TO RUN A
107 // NESTED MESSAGE LOOP IN THE RENDERER!!!
108 // That introduces reentrancy which causes hard to track bugs. You should
109 // find a way to either turn this into an asynchronous message, or one
110 // that can be answered on the IO thread.
111 NOTREACHED() << "Can't send sync messages to UI thread without pumping "
112 "messages in the renderer or else deadlocks can occur if the page "
113 "has windowed plugins! (message type " << message.type() << ")";
114 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
115 reply->set_reply_error();
116 sender->Send(reply);
117 return false;
118 }
119 #endif
120 return true;
121 }
OLDNEW
« no previous file with comments | « content/browser/browser_message_filter.h ('k') | content/browser/renderer_host/render_view_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698