OLD | NEW |
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 #ifndef IPC_IPC_CHANNEL_PROXY_H_ | 5 #ifndef IPC_IPC_CHANNEL_PROXY_H_ |
6 #define IPC_IPC_CHANNEL_PROXY_H_ | 6 #define IPC_IPC_CHANNEL_PROXY_H_ |
7 | 7 |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 // An IPC::ChannelProxy can have a MessageFilter associated with it, which will | 48 // An IPC::ChannelProxy can have a MessageFilter associated with it, which will |
49 // be notified of incoming messages on the IPC::Channel's thread. This gives | 49 // be notified of incoming messages on the IPC::Channel's thread. This gives |
50 // the consumer of IPC::ChannelProxy the ability to respond to incoming | 50 // the consumer of IPC::ChannelProxy the ability to respond to incoming |
51 // messages on this background thread instead of on their own thread, which may | 51 // messages on this background thread instead of on their own thread, which may |
52 // be bogged down with other processing. The result can be greatly improved | 52 // be bogged down with other processing. The result can be greatly improved |
53 // latency for messages that can be handled on a background thread. | 53 // latency for messages that can be handled on a background thread. |
54 // | 54 // |
55 // The consumer of IPC::ChannelProxy is responsible for allocating the Thread | 55 // The consumer of IPC::ChannelProxy is responsible for allocating the Thread |
56 // instance where the IPC::Channel will be created and operated. | 56 // instance where the IPC::Channel will be created and operated. |
57 // | 57 // |
| 58 // Thread-safe send |
| 59 // |
| 60 // A particular |Channel| implementation has thread-safe |Send()| |
| 61 // implementation. If it is supported, ChannelProxy bypasses inter-thread |
| 62 // messaging and calls |Send()| immediately. The |channel_| variable is touched |
| 63 // from multiple threads in this case, so |ChannelProxy::channel_lifetime_lock_| |
| 64 // is used to protect it. |
| 65 // This lock overhead is paid only if the underlying channel supports the |
| 66 // thread-safe send. |
| 67 // |
58 class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { | 68 class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { |
59 public: | 69 public: |
60 // Initializes a channel proxy. The channel_handle and mode parameters are | 70 // Initializes a channel proxy. The channel_handle and mode parameters are |
61 // passed directly to the underlying IPC::Channel. The listener is called on | 71 // passed directly to the underlying IPC::Channel. The listener is called on |
62 // the thread that creates the ChannelProxy. The filter's OnMessageReceived | 72 // the thread that creates the ChannelProxy. The filter's OnMessageReceived |
63 // method is called on the thread where the IPC::Channel is running. The | 73 // method is called on the thread where the IPC::Channel is running. The |
64 // filter may be null if the consumer is not interested in handling messages | 74 // filter may be null if the consumer is not interested in handling messages |
65 // on the background thread. Any message not handled by the filter will be | 75 // on the background thread. Any message not handled by the filter will be |
66 // dispatched to the listener. The given task runner correspond to a thread | 76 // dispatched to the listener. The given task runner correspond to a thread |
67 // on which IPC::Channel is created and used (e.g. IO thread). | 77 // on which IPC::Channel is created and used (e.g. IO thread). |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 void OnSendMessage(scoped_ptr<Message> message_ptr); | 196 void OnSendMessage(scoped_ptr<Message> message_ptr); |
187 void OnAddFilter(); | 197 void OnAddFilter(); |
188 void OnRemoveFilter(MessageFilter* filter); | 198 void OnRemoveFilter(MessageFilter* filter); |
189 | 199 |
190 // Methods called on the listener thread. | 200 // Methods called on the listener thread. |
191 void AddFilter(MessageFilter* filter); | 201 void AddFilter(MessageFilter* filter); |
192 void OnDispatchConnected(); | 202 void OnDispatchConnected(); |
193 void OnDispatchError(); | 203 void OnDispatchError(); |
194 void OnDispatchBadMessage(const Message& message); | 204 void OnDispatchBadMessage(const Message& message); |
195 | 205 |
| 206 // Sends |message| from appropriate thread. |
| 207 void Send(Message* message); |
| 208 void SendFromThisThread(Message* message); |
| 209 void ClearChannel(); |
| 210 |
196 scoped_refptr<base::SingleThreadTaskRunner> listener_task_runner_; | 211 scoped_refptr<base::SingleThreadTaskRunner> listener_task_runner_; |
197 Listener* listener_; | 212 Listener* listener_; |
198 | 213 |
199 // List of filters. This is only accessed on the IPC thread. | 214 // List of filters. This is only accessed on the IPC thread. |
200 std::vector<scoped_refptr<MessageFilter> > filters_; | 215 std::vector<scoped_refptr<MessageFilter> > filters_; |
201 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_; | 216 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_; |
202 | 217 |
203 // Note, channel_ may be set on the Listener thread or the IPC thread. | 218 // Note, channel_ may be set on the Listener thread or the IPC thread. |
204 // But once it has been set, it must only be read or cleared on the IPC | 219 // But once it has been set, it must only be read or cleared on the IPC |
205 // thread. | 220 // thread. |
| 221 // Here is one exception, which is thread-safe send. See the class comment. |
206 scoped_ptr<Channel> channel_; | 222 scoped_ptr<Channel> channel_; |
207 std::string channel_id_; | 223 std::string channel_id_; |
208 bool channel_connected_called_; | 224 bool channel_connected_called_; |
209 | 225 |
210 // Routes a given message to a proper subset of |filters_|, depending | 226 // Routes a given message to a proper subset of |filters_|, depending |
211 // on which message classes a filter might support. | 227 // on which message classes a filter might support. |
212 scoped_ptr<MessageFilterRouter> message_filter_router_; | 228 scoped_ptr<MessageFilterRouter> message_filter_router_; |
213 | 229 |
214 // Holds filters between the AddFilter call on the listerner thread and the | 230 // Holds filters between the AddFilter call on the listerner thread and the |
215 // IPC thread when they're added to filters_. | 231 // IPC thread when they're added to filters_. |
216 std::vector<scoped_refptr<MessageFilter> > pending_filters_; | 232 std::vector<scoped_refptr<MessageFilter> > pending_filters_; |
217 // Lock for pending_filters_. | 233 // Lock for pending_filters_. |
218 base::Lock pending_filters_lock_; | 234 base::Lock pending_filters_lock_; |
219 | 235 |
| 236 // Lock for |channel_| value. This is only relevant in the context of |
| 237 // thread-safe send. |
| 238 base::Lock channel_lifetime_lock_; |
| 239 // Indicates the thread-safe send availability. This is constant once |
| 240 // |channel_| is set. |
| 241 bool channel_send_thread_safe_; |
| 242 |
220 // Cached copy of the peer process ID. Set on IPC but read on both IPC and | 243 // Cached copy of the peer process ID. Set on IPC but read on both IPC and |
221 // listener threads. | 244 // listener threads. |
222 base::ProcessId peer_pid_; | 245 base::ProcessId peer_pid_; |
223 }; | 246 }; |
224 | 247 |
225 Context* context() { return context_.get(); } | 248 Context* context() { return context_.get(); } |
226 | 249 |
227 private: | 250 private: |
228 friend class IpcSecurityTestUtil; | 251 friend class IpcSecurityTestUtil; |
229 | 252 |
230 // By maintaining this indirection (ref-counted) to our internal state, we | 253 // By maintaining this indirection (ref-counted) to our internal state, we |
231 // can safely be destroyed while the background thread continues to do stuff | 254 // can safely be destroyed while the background thread continues to do stuff |
232 // that involves this data. | 255 // that involves this data. |
233 scoped_refptr<Context> context_; | 256 scoped_refptr<Context> context_; |
234 | 257 |
235 // Whether the channel has been initialized. | 258 // Whether the channel has been initialized. |
236 bool did_init_; | 259 bool did_init_; |
237 }; | 260 }; |
238 | 261 |
239 } // namespace IPC | 262 } // namespace IPC |
240 | 263 |
241 #endif // IPC_IPC_CHANNEL_PROXY_H_ | 264 #endif // IPC_IPC_CHANNEL_PROXY_H_ |
OLD | NEW |