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

Side by Side Diff: ipc/ipc_channel_proxy.cc

Issue 780223002: ChannelProxy: Send() from UI thread when ChannelMojo is used. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years 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
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 "ipc/ipc_channel_proxy.h" 5 #include "ipc/ipc_channel_proxy.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
(...skipping 12 matching lines...) Expand all
23 //------------------------------------------------------------------------------ 23 //------------------------------------------------------------------------------
24 24
25 ChannelProxy::Context::Context( 25 ChannelProxy::Context::Context(
26 Listener* listener, 26 Listener* listener,
27 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) 27 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
28 : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), 28 : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()),
29 listener_(listener), 29 listener_(listener),
30 ipc_task_runner_(ipc_task_runner), 30 ipc_task_runner_(ipc_task_runner),
31 channel_connected_called_(false), 31 channel_connected_called_(false),
32 message_filter_router_(new MessageFilterRouter()), 32 message_filter_router_(new MessageFilterRouter()),
33 channel_send_thread_safe_(false),
33 peer_pid_(base::kNullProcessId) { 34 peer_pid_(base::kNullProcessId) {
34 DCHECK(ipc_task_runner_.get()); 35 DCHECK(ipc_task_runner_.get());
35 // The Listener thread where Messages are handled must be a separate thread 36 // The Listener thread where Messages are handled must be a separate thread
36 // to avoid oversubscribing the IO thread. If you trigger this error, you 37 // to avoid oversubscribing the IO thread. If you trigger this error, you
37 // need to either: 38 // need to either:
38 // 1) Create the ChannelProxy on a different thread, or 39 // 1) Create the ChannelProxy on a different thread, or
39 // 2) Just use Channel 40 // 2) Just use Channel
40 // Note, we currently make an exception for a NULL listener. That usage 41 // Note, we currently make an exception for a NULL listener. That usage
41 // basically works, but is outside the intent of ChannelProxy. This support 42 // basically works, but is outside the intent of ChannelProxy. This support
42 // will disappear, so please don't rely on it. See crbug.com/364241 43 // will disappear, so please don't rely on it. See crbug.com/364241
43 DCHECK(!listener || (ipc_task_runner_.get() != listener_task_runner_.get())); 44 DCHECK(!listener || (ipc_task_runner_.get() != listener_task_runner_.get()));
44 } 45 }
45 46
46 ChannelProxy::Context::~Context() { 47 ChannelProxy::Context::~Context() {
47 } 48 }
48 49
49 void ChannelProxy::Context::ClearIPCTaskRunner() { 50 void ChannelProxy::Context::ClearIPCTaskRunner() {
50 ipc_task_runner_ = NULL; 51 ipc_task_runner_ = NULL;
51 } 52 }
52 53
53 void ChannelProxy::Context::CreateChannel(scoped_ptr<ChannelFactory> factory) { 54 void ChannelProxy::Context::CreateChannel(scoped_ptr<ChannelFactory> factory) {
54 DCHECK(!channel_); 55 DCHECK(!channel_);
55 channel_id_ = factory->GetName(); 56 channel_id_ = factory->GetName();
56 channel_ = factory->BuildChannel(this); 57 channel_ = factory->BuildChannel(this);
58 channel_send_thread_safe_ = channel_->IsSendThreadSafe();
57 } 59 }
58 60
59 bool ChannelProxy::Context::TryFilters(const Message& message) { 61 bool ChannelProxy::Context::TryFilters(const Message& message) {
60 DCHECK(message_filter_router_); 62 DCHECK(message_filter_router_);
61 #ifdef IPC_MESSAGE_LOG_ENABLED 63 #ifdef IPC_MESSAGE_LOG_ENABLED
62 Logging* logger = Logging::GetInstance(); 64 Logging* logger = Logging::GetInstance();
63 if (logger->Enabled()) 65 if (logger->Enabled())
64 logger->OnPreDispatchMessage(message); 66 logger->OnPreDispatchMessage(message);
65 #endif 67 #endif
66 68
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 filters_[i]->OnFilterRemoved(); 150 filters_[i]->OnFilterRemoved();
149 } 151 }
150 152
151 // We don't need the filters anymore. 153 // We don't need the filters anymore.
152 message_filter_router_->Clear(); 154 message_filter_router_->Clear();
153 filters_.clear(); 155 filters_.clear();
154 // We don't need the lock, because at this point, the listener thread can't 156 // We don't need the lock, because at this point, the listener thread can't
155 // access it any more. 157 // access it any more.
156 pending_filters_.clear(); 158 pending_filters_.clear();
157 159
158 channel_.reset(); 160 ClearChannel();
159 161
160 // Balance with the reference taken during startup. This may result in 162 // Balance with the reference taken during startup. This may result in
161 // self-destruction. 163 // self-destruction.
162 Release(); 164 Release();
163 } 165 }
164 166
165 void ChannelProxy::Context::Clear() { 167 void ChannelProxy::Context::Clear() {
166 listener_ = NULL; 168 listener_ = NULL;
167 } 169 }
168 170
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 if (listener_) 298 if (listener_)
297 listener_->OnChannelError(); 299 listener_->OnChannelError();
298 } 300 }
299 301
300 // Called on the listener's thread 302 // Called on the listener's thread
301 void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) { 303 void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) {
302 if (listener_) 304 if (listener_)
303 listener_->OnBadMessageReceived(message); 305 listener_->OnBadMessageReceived(message);
304 } 306 }
305 307
308 void ChannelProxy::Context::ClearChannel() {
309 base::AutoLock l(channel_lifetime_lock_);
310 channel_.reset();
311 }
312
313 void ChannelProxy::Context::SendFromThisThread(Message* message) {
314 base::AutoLock l(channel_lifetime_lock_);
315 if (!channel_)
316 return;
317 DCHECK(channel_->IsSendThreadSafe());
318 channel_->Send(message);
319 }
320
321 void ChannelProxy::Context::Send(Message* message) {
322 if (channel_send_thread_safe_) {
323 SendFromThisThread(message);
324 return;
325 }
326
327 ipc_task_runner()->PostTask(
328 FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this,
329 base::Passed(scoped_ptr<Message>(message))));
330 }
331
306 //----------------------------------------------------------------------------- 332 //-----------------------------------------------------------------------------
307 333
308 // static 334 // static
309 scoped_ptr<ChannelProxy> ChannelProxy::Create( 335 scoped_ptr<ChannelProxy> ChannelProxy::Create(
310 const IPC::ChannelHandle& channel_handle, 336 const IPC::ChannelHandle& channel_handle,
311 Channel::Mode mode, 337 Channel::Mode mode,
312 Listener* listener, 338 Listener* listener,
313 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { 339 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
314 scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner)); 340 scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner));
315 channel->Init(channel_handle, mode, true); 341 channel->Init(channel_handle, mode, true);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 bool ChannelProxy::Send(Message* message) { 426 bool ChannelProxy::Send(Message* message) {
401 DCHECK(did_init_); 427 DCHECK(did_init_);
402 428
403 // TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are 429 // TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are
404 // tests that call Send() from a wrong thread. See http://crbug.com/163523. 430 // tests that call Send() from a wrong thread. See http://crbug.com/163523.
405 431
406 #ifdef IPC_MESSAGE_LOG_ENABLED 432 #ifdef IPC_MESSAGE_LOG_ENABLED
407 Logging::GetInstance()->OnSendMessage(message, context_->channel_id()); 433 Logging::GetInstance()->OnSendMessage(message, context_->channel_id());
408 #endif 434 #endif
409 435
410 context_->ipc_task_runner()->PostTask( 436 context_->Send(message);
411 FROM_HERE,
412 base::Bind(&ChannelProxy::Context::OnSendMessage,
413 context_, base::Passed(scoped_ptr<Message>(message))));
414 return true; 437 return true;
415 } 438 }
416 439
417 void ChannelProxy::AddFilter(MessageFilter* filter) { 440 void ChannelProxy::AddFilter(MessageFilter* filter) {
418 DCHECK(CalledOnValidThread()); 441 DCHECK(CalledOnValidThread());
419 442
420 context_->AddFilter(filter); 443 context_->AddFilter(filter);
421 } 444 }
422 445
423 void ChannelProxy::RemoveFilter(MessageFilter* filter) { 446 void ChannelProxy::RemoveFilter(MessageFilter* filter) {
(...skipping 28 matching lines...) Expand all
452 Channel* channel = context_.get()->channel_.get(); 475 Channel* channel = context_.get()->channel_.get();
453 // Channel must have been created first. 476 // Channel must have been created first.
454 DCHECK(channel) << context_.get()->channel_id_; 477 DCHECK(channel) << context_.get()->channel_id_;
455 return channel->TakeClientFileDescriptor(); 478 return channel->TakeClientFileDescriptor();
456 } 479 }
457 #endif 480 #endif
458 481
459 //----------------------------------------------------------------------------- 482 //-----------------------------------------------------------------------------
460 483
461 } // namespace IPC 484 } // namespace IPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698