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 |