| 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 |