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" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 MessageInTransit::EndpointId remote_id); | 125 MessageInTransit::EndpointId remote_id); |
126 | 126 |
127 // See |RawChannel::GetSerializedPlatformHandleSize()|. | 127 // See |RawChannel::GetSerializedPlatformHandleSize()|. |
128 size_t GetSerializedPlatformHandleSize() const; | 128 size_t GetSerializedPlatformHandleSize() const; |
129 | 129 |
130 embedder::PlatformSupport* platform_support() const { | 130 embedder::PlatformSupport* platform_support() const { |
131 return platform_support_; | 131 return platform_support_; |
132 } | 132 } |
133 | 133 |
134 private: | 134 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). |
135 struct EndpointInfo { | 199 struct EndpointInfo { |
136 enum State { | 200 enum State { |
137 // Attached, possibly running or not. | 201 // Attached, possibly running or not. |
138 STATE_NORMAL, | 202 STATE_NORMAL, |
139 // "Zombie" states: | 203 // "Zombie" states: |
140 // Waiting for |DetachMessagePipeEndpoint()| before removing. | 204 // Waiting for |DetachMessagePipeEndpoint()| before removing. |
141 STATE_WAIT_LOCAL_DETACH, | 205 STATE_WAIT_LOCAL_DETACH, |
142 // Waiting for a |kSubtypeChannelRemoveMessagePipeEndpointAck| before | 206 // Waiting for a |kSubtypeChannelRemoveMessagePipeEndpointAck| before |
143 // removing. | 207 // removing. |
144 STATE_WAIT_REMOTE_REMOVE_ACK, | 208 STATE_WAIT_REMOTE_REMOVE_ACK, |
145 // Waiting for both of the above conditions before removing. | |
146 STATE_WAIT_LOCAL_DETACH_AND_REMOTE_REMOVE_ACK, | |
147 }; | 209 }; |
148 | 210 |
149 EndpointInfo(); | 211 EndpointInfo(); |
150 EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port); | 212 EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port); |
151 ~EndpointInfo(); | 213 ~EndpointInfo(); |
152 | 214 |
153 State state; | 215 State state; |
154 scoped_refptr<MessagePipe> message_pipe; | 216 scoped_refptr<MessagePipe> message_pipe; |
155 unsigned port; | 217 unsigned port; |
156 }; | 218 }; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 // be checked for existence before use. | 274 // be checked for existence before use. |
213 MessageInTransit::EndpointId next_local_id_; | 275 MessageInTransit::EndpointId next_local_id_; |
214 | 276 |
215 DISALLOW_COPY_AND_ASSIGN(Channel); | 277 DISALLOW_COPY_AND_ASSIGN(Channel); |
216 }; | 278 }; |
217 | 279 |
218 } // namespace system | 280 } // namespace system |
219 } // namespace mojo | 281 } // namespace mojo |
220 | 282 |
221 #endif // MOJO_SYSTEM_CHANNEL_H_ | 283 #endif // MOJO_SYSTEM_CHANNEL_H_ |
OLD | NEW |