| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 #include "base/thread.h" | 6 #include "base/thread.h" |
| 7 #include "chrome/common/ipc_channel_proxy.h" | 7 #include "chrome/common/ipc_channel_proxy.h" |
| 8 #include "chrome/common/ipc_logging.h" | 8 #include "chrome/common/ipc_logging.h" |
| 9 #include "chrome/common/ipc_message_utils.h" | 9 #include "chrome/common/ipc_message_utils.h" |
| 10 | 10 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #endif | 45 #endif |
| 46 return true; | 46 return true; |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 return false; | 49 return false; |
| 50 } | 50 } |
| 51 | 51 |
| 52 // Called on the IPC::Channel thread | 52 // Called on the IPC::Channel thread |
| 53 void ChannelProxy::Context::OnMessageReceived(const Message& message) { | 53 void ChannelProxy::Context::OnMessageReceived(const Message& message) { |
| 54 // First give a chance to the filters to process this message. | 54 // First give a chance to the filters to process this message. |
| 55 if (TryFilters(message)) | 55 if (!TryFilters(message)) |
| 56 return; | 56 OnMessageReceivedNoFilter(message); |
| 57 } |
| 57 | 58 |
| 59 // Called on the IPC::Channel thread |
| 60 void ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) { |
| 58 // NOTE: This code relies on the listener's message loop not going away while | 61 // NOTE: This code relies on the listener's message loop not going away while |
| 59 // this thread is active. That should be a reasonable assumption, but it | 62 // this thread is active. That should be a reasonable assumption, but it |
| 60 // feels risky. We may want to invent some more indirect way of referring to | 63 // feels risky. We may want to invent some more indirect way of referring to |
| 61 // a MessageLoop if this becomes a problem. | 64 // a MessageLoop if this becomes a problem. |
| 62 | |
| 63 listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 65 listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 64 this, &Context::OnDispatchMessage, message)); | 66 this, &Context::OnDispatchMessage, message)); |
| 65 } | 67 } |
| 66 | 68 |
| 67 // Called on the IPC::Channel thread | 69 // Called on the IPC::Channel thread |
| 68 void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) { | 70 void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) { |
| 69 for (size_t i = 0; i < filters_.size(); ++i) | 71 for (size_t i = 0; i < filters_.size(); ++i) |
| 70 filters_[i]->OnChannelConnected(peer_pid); | 72 filters_[i]->OnChannelConnected(peer_pid); |
| 71 | 73 |
| 72 // See above comment about using listener_message_loop_ here. | 74 // See above comment about using listener_message_loop_ here. |
| 73 listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 75 listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 74 this, &Context::OnDispatchConnected, peer_pid)); | 76 this, &Context::OnDispatchConnected, peer_pid)); |
| 75 } | 77 } |
| 76 | 78 |
| 77 // Called on the IPC::Channel thread | 79 // Called on the IPC::Channel thread |
| 78 void ChannelProxy::Context::OnChannelError() { | 80 void ChannelProxy::Context::OnChannelError() { |
| 79 // See above comment about using listener_message_loop_ here. | 81 // See above comment about using listener_message_loop_ here. |
| 80 listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 82 listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 81 this, &Context::OnDispatchError)); | 83 this, &Context::OnDispatchError)); |
| 82 } | 84 } |
| 83 | 85 |
| 84 // Called on the IPC::Channel thread | 86 // Called on the IPC::Channel thread |
| 85 void ChannelProxy::Context::OnOpenChannel() { | 87 void ChannelProxy::Context::OnChannelOpened() { |
| 86 DCHECK(channel_ != NULL); | 88 DCHECK(channel_ != NULL); |
| 87 | 89 |
| 88 // Assume a reference to ourselves on behalf of this thread. This reference | 90 // Assume a reference to ourselves on behalf of this thread. This reference |
| 89 // will be released when we are closed. | 91 // will be released when we are closed. |
| 90 AddRef(); | 92 AddRef(); |
| 91 | 93 |
| 92 if (!channel_->Connect()) { | 94 if (!channel_->Connect()) { |
| 93 OnChannelError(); | 95 OnChannelError(); |
| 94 return; | 96 return; |
| 95 } | 97 } |
| 96 | 98 |
| 97 for (size_t i = 0; i < filters_.size(); ++i) | 99 for (size_t i = 0; i < filters_.size(); ++i) |
| 98 filters_[i]->OnFilterAdded(channel_); | 100 filters_[i]->OnFilterAdded(channel_); |
| 99 } | 101 } |
| 100 | 102 |
| 101 // Called on the IPC::Channel thread | 103 // Called on the IPC::Channel thread |
| 102 void ChannelProxy::Context::OnCloseChannel() { | 104 void ChannelProxy::Context::OnChannelClosed() { |
| 103 // It's okay for IPC::ChannelProxy::Close to be called more than once, which | 105 // It's okay for IPC::ChannelProxy::Close to be called more than once, which |
| 104 // would result in this branch being taken. | 106 // would result in this branch being taken. |
| 105 if (!channel_) | 107 if (!channel_) |
| 106 return; | 108 return; |
| 107 | 109 |
| 108 for (size_t i = 0; i < filters_.size(); ++i) { | 110 for (size_t i = 0; i < filters_.size(); ++i) { |
| 109 filters_[i]->OnChannelClosing(); | 111 filters_[i]->OnChannelClosing(); |
| 110 filters_[i]->OnFilterRemoved(); | 112 filters_[i]->OnFilterRemoved(); |
| 111 } | 113 } |
| 112 | 114 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 // the pipe immediately, it is possible for a listener to attempt | 215 // the pipe immediately, it is possible for a listener to attempt |
| 214 // to connect and get an error since the pipe doesn't exist yet. | 216 // to connect and get an error since the pipe doesn't exist yet. |
| 215 context_->CreateChannel(channel_id, mode); | 217 context_->CreateChannel(channel_id, mode); |
| 216 } else { | 218 } else { |
| 217 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 219 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 218 context_.get(), &Context::CreateChannel, channel_id, mode)); | 220 context_.get(), &Context::CreateChannel, channel_id, mode)); |
| 219 } | 221 } |
| 220 | 222 |
| 221 // complete initialization on the background thread | 223 // complete initialization on the background thread |
| 222 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 224 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 223 context_.get(), &Context::OnOpenChannel)); | 225 context_.get(), &Context::OnChannelOpened)); |
| 224 } | 226 } |
| 225 | 227 |
| 226 void ChannelProxy::Close() { | 228 void ChannelProxy::Close() { |
| 227 // Clear the backpointer to the listener so that any pending calls to | 229 // Clear the backpointer to the listener so that any pending calls to |
| 228 // Context::OnDispatchMessage or OnDispatchError will be ignored. It is | 230 // Context::OnDispatchMessage or OnDispatchError will be ignored. It is |
| 229 // possible that the channel could be closed while it is receiving messages! | 231 // possible that the channel could be closed while it is receiving messages! |
| 230 context_->clear(); | 232 context_->Clear(); |
| 231 | 233 |
| 232 if (MessageLoop::current() == context_->ipc_message_loop()) { | 234 if (context_->ipc_message_loop()) { |
| 233 // We're being destructed on the IPC thread, so no need to use the message | |
| 234 // loop as it might go away. | |
| 235 context_->OnCloseChannel(); | |
| 236 } else { | |
| 237 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 235 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 238 context_.get(), &Context::OnCloseChannel)); | 236 context_.get(), &Context::OnChannelClosed)); |
| 239 } | 237 } |
| 240 } | 238 } |
| 241 | 239 |
| 242 bool ChannelProxy::Send(Message* message) { | 240 bool ChannelProxy::Send(Message* message) { |
| 243 #ifdef IPC_MESSAGE_LOG_ENABLED | 241 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 244 Logging::current()->OnSendMessage(message, context_->channel_id()); | 242 Logging::current()->OnSendMessage(message, context_->channel_id()); |
| 245 #endif | 243 #endif |
| 246 | 244 |
| 247 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 245 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 248 context_.get(), &Context::OnSendMessage, message)); | 246 context_.get(), &Context::OnSendMessage, message)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 259 | 257 |
| 260 void ChannelProxy::RemoveFilter(MessageFilter* filter) { | 258 void ChannelProxy::RemoveFilter(MessageFilter* filter) { |
| 261 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 259 context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 262 context_.get(), &Context::OnRemoveFilter, filter)); | 260 context_.get(), &Context::OnRemoveFilter, filter)); |
| 263 } | 261 } |
| 264 | 262 |
| 265 //----------------------------------------------------------------------------- | 263 //----------------------------------------------------------------------------- |
| 266 | 264 |
| 267 } // namespace IPC | 265 } // namespace IPC |
| 268 | 266 |
| OLD | NEW |