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

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

Issue 1723473003: Remove limitation that renderer can't send sync IPCs to the UI thread in the browser. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 | « content/public/browser/browser_message_filter.h ('k') | no next file » | 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 #include "content/public/browser/browser_message_filter.h" 5 #include "content/public/browser/browser_message_filter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 if (runner.get()) { 62 if (runner.get()) {
63 runner->PostTask( 63 runner->PostTask(
64 FROM_HERE, 64 FROM_HERE,
65 base::Bind( 65 base::Bind(
66 base::IgnoreResult(&Internal::DispatchMessage), this, message)); 66 base::IgnoreResult(&Internal::DispatchMessage), this, message));
67 return true; 67 return true;
68 } 68 }
69 return DispatchMessage(message); 69 return DispatchMessage(message);
70 } 70 }
71 71
72 if (thread == BrowserThread::UI &&
73 !BrowserMessageFilter::CheckCanDispatchOnUI(message, filter_.get())) {
74 return true;
75 }
76
77 BrowserThread::PostTask( 72 BrowserThread::PostTask(
78 thread, FROM_HERE, 73 thread, FROM_HERE,
79 base::Bind( 74 base::Bind(
80 base::IgnoreResult(&Internal::DispatchMessage), this, message)); 75 base::IgnoreResult(&Internal::DispatchMessage), this, message));
81 return true; 76 return true;
82 } 77 }
83 78
84 bool GetSupportedMessageClasses( 79 bool GetSupportedMessageClasses(
85 std::vector<uint32_t>* supported_message_classes) const override { 80 std::vector<uint32_t>* supported_message_classes) const override {
86 supported_message_classes->assign( 81 supported_message_classes->assign(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 145
151 delete message; 146 delete message;
152 return false; 147 return false;
153 } 148 }
154 149
155 base::TaskRunner* BrowserMessageFilter::OverrideTaskRunnerForMessage( 150 base::TaskRunner* BrowserMessageFilter::OverrideTaskRunnerForMessage(
156 const IPC::Message& message) { 151 const IPC::Message& message) {
157 return nullptr; 152 return nullptr;
158 } 153 }
159 154
160 bool BrowserMessageFilter::CheckCanDispatchOnUI(const IPC::Message& message,
161 IPC::Sender* sender) {
162 #if defined(OS_WIN)
163 // On Windows there's a potential deadlock with sync messsages going in
164 // a circle from browser -> plugin -> renderer -> browser.
165 // On Linux we can avoid this by avoiding sync messages from browser->plugin.
166 // On Mac we avoid this by not supporting windowed plugins.
167 if (message.is_sync() && !message.is_caller_pumping_messages()) {
168 // NOTE: IF YOU HIT THIS ASSERT, THE SOLUTION IS ALMOST NEVER TO RUN A
169 // NESTED MESSAGE LOOP IN THE RENDERER!!!
170 // That introduces reentrancy which causes hard to track bugs. You should
171 // find a way to either turn this into an asynchronous message, or one
172 // that can be answered on the IO thread.
173 NOTREACHED() << "Can't send sync messages to UI thread without pumping "
174 "messages in the renderer or else deadlocks can occur if the page "
175 "has windowed plugins! (message type " << message.type() << ")";
176 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
177 reply->set_reply_error();
178 sender->Send(reply);
179 return false;
180 }
181 #endif
182 return true;
183 }
184
185 void BrowserMessageFilter::ShutdownForBadMessage() { 155 void BrowserMessageFilter::ShutdownForBadMessage() {
186 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 156 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
187 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) 157 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC))
188 return; 158 return;
189 159
190 BrowserChildProcessHostImpl::HistogramBadMessageTerminated( 160 BrowserChildProcessHostImpl::HistogramBadMessageTerminated(
191 PROCESS_TYPE_RENDERER); 161 PROCESS_TYPE_RENDERER);
192 162
193 #if defined(OS_ANDROID) 163 #if defined(OS_ANDROID)
194 // Android requires a different approach for killing. 164 // Android requires a different approach for killing.
195 StopChildProcess(peer_process_.Handle()); 165 StopChildProcess(peer_process_.Handle());
196 #else 166 #else
197 peer_process_.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false); 167 peer_process_.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
198 #endif 168 #endif
199 } 169 }
200 170
201 BrowserMessageFilter::~BrowserMessageFilter() { 171 BrowserMessageFilter::~BrowserMessageFilter() {
202 } 172 }
203 173
204 IPC::MessageFilter* BrowserMessageFilter::GetFilter() { 174 IPC::MessageFilter* BrowserMessageFilter::GetFilter() {
205 // We create this on demand so that if a filter is used in a unit test but 175 // We create this on demand so that if a filter is used in a unit test but
206 // never attached to a channel, we don't leak Internal and this; 176 // never attached to a channel, we don't leak Internal and this;
207 DCHECK(!internal_) << "Should only be called once."; 177 DCHECK(!internal_) << "Should only be called once.";
208 internal_ = new Internal(this); 178 internal_ = new Internal(this);
209 return internal_; 179 return internal_;
210 } 180 }
211 181
212 } // namespace content 182 } // namespace content
OLDNEW
« no previous file with comments | « content/public/browser/browser_message_filter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698