OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 MOJO_SYSTEM_CHANNEL_H_ | 5 #ifndef MOJO_SYSTEM_CHANNEL_H_ |
6 #define MOJO_SYSTEM_CHANNEL_H_ | 6 #define MOJO_SYSTEM_CHANNEL_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/strings/string_piece.h" | 15 #include "base/strings/string_piece.h" |
16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
17 #include "base/threading/thread_checker.h" | 17 #include "base/threading/thread_checker.h" |
18 #include "mojo/embedder/scoped_platform_handle.h" | 18 #include "mojo/embedder/scoped_platform_handle.h" |
19 #include "mojo/public/c/system/types.h" | 19 #include "mojo/public/c/system/types.h" |
| 20 #include "mojo/system/channel_endpoint.h" |
20 #include "mojo/system/message_in_transit.h" | 21 #include "mojo/system/message_in_transit.h" |
21 #include "mojo/system/message_pipe.h" | 22 #include "mojo/system/message_pipe.h" |
22 #include "mojo/system/raw_channel.h" | 23 #include "mojo/system/raw_channel.h" |
23 #include "mojo/system/system_impl_export.h" | 24 #include "mojo/system/system_impl_export.h" |
24 | 25 |
25 namespace mojo { | 26 namespace mojo { |
26 | 27 |
27 namespace embedder { | 28 namespace embedder { |
28 class PlatformSupport; | 29 class PlatformSupport; |
29 } | 30 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 MessageInTransit::EndpointId remote_id); | 126 MessageInTransit::EndpointId remote_id); |
126 | 127 |
127 // See |RawChannel::GetSerializedPlatformHandleSize()|. | 128 // See |RawChannel::GetSerializedPlatformHandleSize()|. |
128 size_t GetSerializedPlatformHandleSize() const; | 129 size_t GetSerializedPlatformHandleSize() const; |
129 | 130 |
130 embedder::PlatformSupport* platform_support() const { | 131 embedder::PlatformSupport* platform_support() const { |
131 return platform_support_; | 132 return platform_support_; |
132 } | 133 } |
133 | 134 |
134 private: | 135 private: |
135 // Terminology: | |
136 // - "Message pipe endpoint": In the implementation, a |MessagePipe| owns | |
137 // two |MessagePipeEndpoint| objects, one for each port. The | |
138 // |MessagePipeEndpoint| objects are only accessed via the |MessagePipe| | |
139 // (which has the lock), with the additional information of the port | |
140 // number. So as far as the channel is concerned, a message pipe endpoint | |
141 // is a pointer to a |MessagePipe| together with the port number. | |
142 // - The value of |port| in |EndpointInfo| refers to the | |
143 // |ProxyMessagePipeEndpoint| (i.e., the endpoint that is logically on | |
144 // the other side). Messages received by a channel for a message pipe | |
145 // are thus written to the *peer* of this port. | |
146 // - "Attached"/"detached": A message pipe endpoint is attached to a channel | |
147 // if it has a pointer to it. It must be detached before the channel gives | |
148 // up its pointer to it in order to break a reference cycle. (This cycle | |
149 // is needed to allow a channel to be shut down cleanly, without shutting | |
150 // down everything else first.) | |
151 // - "Running" (message pipe endpoint): A message pipe endpoint is running | |
152 // if messages written to it (via some |MessagePipeDispatcher|, to which | |
153 // some |MojoHandle| is assigned) are being transmitted through the | |
154 // channel. | |
155 // - Before a message pipe endpoint is run, it will queue messages. | |
156 // - When a message pipe endpoint is detached from a channel, it is also | |
157 // taken out of the running state. After that point, messages should | |
158 // no longer be written to it. | |
159 // - "Normal" message pipe endpoint (state): The channel itself does not | |
160 // have knowledge of whether a message pipe endpoint has started running | |
161 // yet. It will *receive* messages for a message pipe in either state (but | |
162 // the message pipe endpoint won't *send* messages to the channel if it | |
163 // has not started running). | |
164 // - "Zombie" message pipe endpoint (state): A message pipe endpoint is a | |
165 // zombie if it is still in |local_id_to_endpoint_info_map_|, but the | |
166 // channel is no longer forwarding messages to it (even if it may still be | |
167 // receiving messages for it). | |
168 // - There are various types of zombies, depending on the reason the | |
169 // message pipe endpoint cannot yet be removed. | |
170 // - If the remote side is closed, it will send a "remove" control | |
171 // message. After the channel receives that message (to which it | |
172 // responds with a "remove ack" control message), it knows that it | |
173 // shouldn't receive any more messages for that message pipe endpoint | |
174 // (local ID), but it must wait for the endpoint to detach. (It can't | |
175 // do so without a race, since it can't call into the message pipe | |
176 // under |lock_|.) [TODO(vtl): When I add remotely-allocated IDs, | |
177 // we'll have to remove the |EndpointInfo| from | |
178 // |local_id_to_endpoint_info_map_| -- i.e., remove the local ID, | |
179 // since it's no longer valid and may be reused by the remote side -- | |
180 // and keep the |EndpointInfo| alive in some other way.] | |
181 // - If the local side is closed and the message pipe endpoint was | |
182 // already running (so there are no queued messages left to send), it | |
183 // will detach the endpoint, and send a "remove" control message. | |
184 // However, the channel may still receive messages for that endpoint | |
185 // until it receives a "remove ack" control message. | |
186 // - If the local side is closed but the message pipe endpoint was not | |
187 // yet running , the detaching is delayed until after it is run and | |
188 // all the queued messages are sent to the channel. On being detached, | |
189 // things proceed as in one of the above cases. The endpoint is *not* | |
190 // a zombie until it is detached (or a "remove" message is received). | |
191 // [TODO(vtl): Maybe we can get rid of this case? It'd only not yet be | |
192 // running since under the current scheme it wouldn't have a remote ID | |
193 // yet.] | |
194 // - Note that even if the local side is closed, it may still receive a | |
195 // "remove" message from the other side (if the other side is closed | |
196 // simultaneously, and both sides send "remove" messages). In that | |
197 // case, it must still remain alive until it receives the "remove | |
198 // ack" (and it must ack the "remove" message that it received). | |
199 struct EndpointInfo { | |
200 enum State { | |
201 // Attached, possibly running or not. | |
202 STATE_NORMAL, | |
203 // "Zombie" states: | |
204 // Waiting for |DetachMessagePipeEndpoint()| before removing. | |
205 STATE_WAIT_LOCAL_DETACH, | |
206 // Waiting for a |kSubtypeChannelRemoveMessagePipeEndpointAck| before | |
207 // removing. | |
208 STATE_WAIT_REMOTE_REMOVE_ACK, | |
209 }; | |
210 | |
211 EndpointInfo(); | |
212 EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port); | |
213 ~EndpointInfo(); | |
214 | |
215 State state; | |
216 scoped_refptr<MessagePipe> message_pipe; | |
217 unsigned port; | |
218 }; | |
219 | |
220 friend class base::RefCountedThreadSafe<Channel>; | 136 friend class base::RefCountedThreadSafe<Channel>; |
221 virtual ~Channel(); | 137 virtual ~Channel(); |
222 | 138 |
223 // |RawChannel::Delegate| implementation: | 139 // |RawChannel::Delegate| implementation: |
224 virtual void OnReadMessage( | 140 virtual void OnReadMessage( |
225 const MessageInTransit::View& message_view, | 141 const MessageInTransit::View& message_view, |
226 embedder::ScopedPlatformHandleVectorPtr platform_handles) OVERRIDE; | 142 embedder::ScopedPlatformHandleVectorPtr platform_handles) OVERRIDE; |
227 virtual void OnError(Error error) OVERRIDE; | 143 virtual void OnError(Error error) OVERRIDE; |
228 | 144 |
229 // Helpers for |OnReadMessage|: | 145 // Helpers for |OnReadMessage|: |
(...skipping 20 matching lines...) Expand all Loading... |
250 bool SendControlMessage(MessageInTransit::Subtype subtype, | 166 bool SendControlMessage(MessageInTransit::Subtype subtype, |
251 MessageInTransit::EndpointId source_id, | 167 MessageInTransit::EndpointId source_id, |
252 MessageInTransit::EndpointId destination_id); | 168 MessageInTransit::EndpointId destination_id); |
253 | 169 |
254 base::ThreadChecker creation_thread_checker_; | 170 base::ThreadChecker creation_thread_checker_; |
255 | 171 |
256 embedder::PlatformSupport* const platform_support_; | 172 embedder::PlatformSupport* const platform_support_; |
257 | 173 |
258 // Note: |MessagePipe|s MUST NOT be used under |lock_|. I.e., |lock_| can only | 174 // Note: |MessagePipe|s MUST NOT be used under |lock_|. I.e., |lock_| can only |
259 // be acquired after |MessagePipe::lock_|, never before. Thus to call into a | 175 // be acquired after |MessagePipe::lock_|, never before. Thus to call into a |
260 // |MessagePipe|, a reference should be acquired from | 176 // |MessagePipe|, a reference to the |MessagePipe| should be acquired from |
261 // |local_id_to_endpoint_info_map_| under |lock_| (e.g., by copying the | 177 // |local_id_to_endpoint_map_| under |lock_| and then the lock released. |
262 // |EndpointInfo|) and then the lock released. | |
263 base::Lock lock_; // Protects the members below. | 178 base::Lock lock_; // Protects the members below. |
264 | 179 |
265 scoped_ptr<RawChannel> raw_channel_; | 180 scoped_ptr<RawChannel> raw_channel_; |
266 bool is_running_; | 181 bool is_running_; |
267 // Set when |WillShutdownSoon()| is called. | 182 // Set when |WillShutdownSoon()| is called. |
268 bool is_shutting_down_; | 183 bool is_shutting_down_; |
269 | 184 |
270 typedef base::hash_map<MessageInTransit::EndpointId, EndpointInfo> | 185 typedef base::hash_map<MessageInTransit::EndpointId, |
271 IdToEndpointInfoMap; | 186 scoped_refptr<ChannelEndpoint> > IdToEndpointMap; |
272 IdToEndpointInfoMap local_id_to_endpoint_info_map_; | 187 IdToEndpointMap local_id_to_endpoint_map_; |
273 // The next local ID to try (when allocating new local IDs). Note: It should | 188 // The next local ID to try (when allocating new local IDs). Note: It should |
274 // be checked for existence before use. | 189 // be checked for existence before use. |
275 MessageInTransit::EndpointId next_local_id_; | 190 MessageInTransit::EndpointId next_local_id_; |
276 | 191 |
277 DISALLOW_COPY_AND_ASSIGN(Channel); | 192 DISALLOW_COPY_AND_ASSIGN(Channel); |
278 }; | 193 }; |
279 | 194 |
280 } // namespace system | 195 } // namespace system |
281 } // namespace mojo | 196 } // namespace mojo |
282 | 197 |
283 #endif // MOJO_SYSTEM_CHANNEL_H_ | 198 #endif // MOJO_SYSTEM_CHANNEL_H_ |
OLD | NEW |