15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/ipc_channel_proxy.h" 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ipc/ipc_channel_factory.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_listener.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/message_filter.h" 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/message_filter_router.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChannelProxy::Context::Context( 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Listener* listener, 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_(listener), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_task_runner_(ipc_task_runner), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_connected_called_(false), 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_filter_router_(new MessageFilterRouter()), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_pid_(base::kNullProcessId) { 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(ipc_task_runner_.get()); 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The Listener thread where Messages are handled must be a separate thread 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // to avoid oversubscribing the IO thread. If you trigger this error, you 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // need to either: 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // 1) Create the ChannelProxy on a different thread, or 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // 2) Just use Channel 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Note, we currently make an exception for a NULL listener. That usage 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // basically works, but is outside the intent of ChannelProxy. This support 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // will disappear, so please don't rely on it. See crbug.com/364241 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(!listener || (ipc_task_runner_.get() != listener_task_runner_.get())); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::Context::~Context() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::ClearIPCTaskRunner() { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_task_runner_ = NULL; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChannelProxy::Context::CreateChannel(scoped_ptr<ChannelFactory> factory) { 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!channel_); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_id_ = factory->GetName(); 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_ = factory->BuildChannel(this); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::TryFilters(const Message& message) { 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(message_filter_router_); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Logging* logger = Logging::GetInstance(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (logger->Enabled()) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logger->OnPreDispatchMessage(message); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (message_filter_router_->TryFilters(message)) { 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (message.dispatch_error()) { 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listener_task_runner_->PostTask( 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnDispatchBadMessage, this, message)); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (logger->Enabled()) 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) logger->OnPostDispatchMessage(message, channel_id_); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::OnMessageReceived(const Message& message) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First give a chance to the filters to process this message. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TryFilters(message)) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnMessageReceivedNoFilter(message); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_task_runner_->PostTask( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnDispatchMessage, this, message)); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) { 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We cache off the peer_pid so it can be safely accessed from both threads. 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) peer_pid_ = channel_->GetPeerPID(); 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add any pending filters. This avoids a race condition where someone 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // creates a ChannelProxy, calls AddFilter, and then right after starts the 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // peer process. The IO thread could receive a message before the task to add 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the filter is run on the IO thread. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAddFilter(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above comment about using listener_task_runner_ here. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_task_runner_->PostTask( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnDispatchConnected, this)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelError() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < filters_.size(); ++i) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_[i]->OnChannelError(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above comment about using listener_task_runner_ here. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_task_runner_->PostTask( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnDispatchError, this)); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelOpened() { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(channel_ != NULL); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume a reference to ourselves on behalf of this thread. This reference 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be released when we are closed. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!channel_->Connect()) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnChannelError(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < filters_.size(); ++i) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_[i]->OnFilterAdded(channel_.get()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelClosed() { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's okay for IPC::ChannelProxy::Close to be called more than once, which 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would result in this branch being taken. 14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!channel_) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < filters_.size(); ++i) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_[i]->OnChannelClosing(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_[i]->OnFilterRemoved(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need the filters anymore. 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_filter_router_->Clear(); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) filters_.clear(); 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We don't need the lock, because at this point, the listener thread can't 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // access it any more. 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_filters_.clear(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.reset(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Balance with the reference taken during startup. This may result in 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // self-destruction. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::Clear() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_ = NULL; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnSendMessage(scoped_ptr<Message> message) { 17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!channel_) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnChannelClosed(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!channel_->Send(message.release())) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnChannelError(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnAddFilter() { 18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Our OnChannelConnected method has not yet been called, so we can't be 18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // sure that channel_ is valid yet. When OnChannelConnected *is* called, 18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // it invokes OnAddFilter, so any pending filter(s) will be added at that 18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // time. 18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (peer_pid_ == base::kNullProcessId) 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<scoped_refptr<MessageFilter> > new_filters; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(pending_filters_lock_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_filters.swap(pending_filters_); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < new_filters.size(); ++i) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_.push_back(new_filters[i]); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_filter_router_->AddFilter(new_filters[i].get()); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The channel has already been created and connected, so we need to 20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // inform the filters right now. 20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new_filters[i]->OnFilterAdded(channel_.get()); 20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new_filters[i]->OnChannelConnected(peer_pid_); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnRemoveFilter(MessageFilter* filter) { 20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (peer_pid_ == base::kNullProcessId) { 21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The channel is not yet connected, so any filters are still pending. 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::AutoLock auto_lock(pending_filters_lock_); 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (size_t i = 0; i < pending_filters_.size(); ++i) { 21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (pending_filters_[i].get() == filter) { 21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) filter->OnFilterRemoved(); 21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_filters_.erase(pending_filters_.begin() + i); 21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!channel_) 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; // The filters have already been deleted. 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_filter_router_->RemoveFilter(filter); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < filters_.size(); ++i) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filters_[i].get() == filter) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->OnFilterRemoved(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_.erase(filters_.begin() + i); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "filter to be removed not found"; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::AddFilter(MessageFilter* filter) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(pending_filters_lock_); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_filters_.push_back(make_scoped_refptr(filter)); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_task_runner_->PostTask( 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnAddFilter, this)); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchMessage(const Message& message) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Logging* logger = Logging::GetInstance(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logger->GetMessageText(message.type(), &name, &message, NULL); 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TRACE_EVENT1("ipc", "ChannelProxy::Context::OnDispatchMessage", 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", name); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TRACE_EVENT2("ipc", "ChannelProxy::Context::OnDispatchMessage", 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "class", IPC_MESSAGE_ID_CLASS(message.type()), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "line", IPC_MESSAGE_ID_LINE(message.type())); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listener_) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnDispatchConnected(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.type() == IPC_LOGGING_ID) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logger->OnReceivedLoggingMessage(message); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (logger->Enabled()) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logger->OnPreDispatchMessage(message); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->OnMessageReceived(message); 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (message.dispatch_error()) 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listener_->OnBadMessageReceived(message); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (logger->Enabled()) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logger->OnPostDispatchMessage(message, channel_id_); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchConnected() { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (channel_connected_called_) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_connected_called_ = true; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listener_) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->OnChannelConnected(peer_pid_); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchError() { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listener_) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->OnChannelError(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called on the listener's thread 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) { 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (listener_) 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listener_->OnBadMessageReceived(message); 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_ptr<ChannelProxy> ChannelProxy::Create( 31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const IPC::ChannelHandle& channel_handle, 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Channel::Mode mode, 31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Listener* listener, 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { 31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner)); 31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel->Init(channel_handle, mode, true); 31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return channel.Pass(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_ptr<ChannelProxy> ChannelProxy::Create( 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ChannelFactory> factory, 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Listener* listener, 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner)); 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel->Init(factory.Pass(), true); 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return channel.Pass(); 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::ChannelProxy(Context* context) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : context_(context), 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_init_(false) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChannelProxy::ChannelProxy( 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Listener* listener, 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) 33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : context_(new Context(listener, ipc_task_runner)), did_init_(false) { 33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::~ChannelProxy() { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Channel::Mode mode, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool create_pipe_now) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we are creating a server on POSIX, we need its file descriptor 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be created immediately so that it can be accessed and passed 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to other processes. Forcing it to be created immediately avoids 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // race conditions that may otherwise arise. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mode & Channel::MODE_SERVER_FLAG) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_pipe_now = true; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_POSIX) 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Init(ChannelFactory::Create(channel_handle, mode), 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) create_pipe_now); 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChannelProxy::Init(scoped_ptr<ChannelFactory> factory, 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool create_pipe_now) { 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(CalledOnValidThread()); 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!did_init_); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (create_pipe_now) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the channel immediately. This effectively sets up the 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // low-level pipe so that the client can connect. Without creating 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the pipe immediately, it is possible for a listener to attempt 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to connect and get an error since the pipe doesn't exist yet. 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context_->CreateChannel(factory.Pass()); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->ipc_task_runner()->PostTask( 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, base::Bind(&Context::CreateChannel, 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context_.get(), Passed(factory.Pass()))); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // complete initialization on the background thread 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->ipc_task_runner()->PostTask( 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnChannelOpened, context_.get())); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_init_ = true; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Close() { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the backpointer to the listener so that any pending calls to 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Context::OnDispatchMessage or OnDispatchError will be ignored. It is 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible that the channel could be closed while it is receiving messages! 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->Clear(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_->ipc_task_runner()) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->ipc_task_runner()->PostTask( 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnChannelClosed, context_.get())); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Send(Message* message) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(did_init_); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // tests that call Send() from a wrong thread. See http://crbug.com/163523. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Logging::GetInstance()->OnSendMessage(message, context_->channel_id()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->ipc_task_runner()->PostTask( 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ChannelProxy::Context::OnSendMessage, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_, base::Passed(scoped_ptr<Message>(message)))); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::AddFilter(MessageFilter* filter) { 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->AddFilter(filter); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::RemoveFilter(MessageFilter* filter) { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->ipc_task_runner()->PostTask( 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(), 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(filter))); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::ClearIPCTaskRunner() { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context()->ClearIPCTaskRunner(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_NACL) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the TODO regarding lazy initialization of the channel in 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ChannelProxy::Init(). 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelProxy::GetClientFileDescriptor() { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Channel* channel = context_.get()->channel_.get(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Channel must have been created first. 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(channel) << context_.get()->channel_id_; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel->GetClientFileDescriptor(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelProxy::TakeClientFileDescriptor() { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Channel* channel = context_.get()->channel_.get(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Channel must have been created first. 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(channel) << context_.get()->channel_id_; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel->TakeClientFileDescriptor(); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace IPC 462