| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_EDK_SYSTEM_CHANNEL_ENDPOINT_H_ | 5 #ifndef MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_H_ |
| 6 #define MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_H_ | 6 #define MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "mojo/edk/system/channel_endpoint_id.h" | 10 #include "mojo/edk/system/channel_endpoint_id.h" |
| 11 #include "mojo/edk/system/message_in_transit_queue.h" | 11 #include "mojo/edk/system/message_in_transit_queue.h" |
| 12 #include "mojo/edk/system/mutex.h" | 12 #include "mojo/edk/system/mutex.h" |
| 13 #include "mojo/edk/system/ref_counted.h" | 13 #include "mojo/edk/util/ref_counted.h" |
| 14 #include "mojo/edk/system/ref_ptr.h" | 14 #include "mojo/edk/util/ref_ptr.h" |
| 15 #include "mojo/public/cpp/system/macros.h" | 15 #include "mojo/public/cpp/system/macros.h" |
| 16 | 16 |
| 17 namespace mojo { | 17 namespace mojo { |
| 18 namespace system { | 18 namespace system { |
| 19 | 19 |
| 20 class Channel; | 20 class Channel; |
| 21 class ChannelEndpointClient; | 21 class ChannelEndpointClient; |
| 22 class MessageInTransit; | 22 class MessageInTransit; |
| 23 | 23 |
| 24 // TODO(vtl): The plan: | 24 // TODO(vtl): The plan: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // things proceed as in one of the above cases. The endpoint is *not* | 102 // things proceed as in one of the above cases. The endpoint is *not* |
| 103 // a zombie until it is detached (or a "remove" message is received). | 103 // a zombie until it is detached (or a "remove" message is received). |
| 104 // [TODO(vtl): Maybe we can get rid of this case? It'd only not yet be | 104 // [TODO(vtl): Maybe we can get rid of this case? It'd only not yet be |
| 105 // running since under the current scheme it wouldn't have a remote ID | 105 // running since under the current scheme it wouldn't have a remote ID |
| 106 // yet.] | 106 // yet.] |
| 107 // - Note that even if the local side is closed, it may still receive a | 107 // - Note that even if the local side is closed, it may still receive a |
| 108 // "remove" message from the other side (if the other side is closed | 108 // "remove" message from the other side (if the other side is closed |
| 109 // simultaneously, and both sides send "remove" messages). In that | 109 // simultaneously, and both sides send "remove" messages). In that |
| 110 // case, it must still remain alive until it receives the "remove | 110 // case, it must still remain alive until it receives the "remove |
| 111 // ack" (and it must ack the "remove" message that it received). | 111 // ack" (and it must ack the "remove" message that it received). |
| 112 class ChannelEndpoint final : public RefCountedThreadSafe<ChannelEndpoint> { | 112 class ChannelEndpoint final |
| 113 : public util::RefCountedThreadSafe<ChannelEndpoint> { |
| 113 public: | 114 public: |
| 114 // Note: Use |MakeRefCounted<ChannelEndpoint>()|. | 115 // Note: Use |util::MakeRefCounted<ChannelEndpoint>()|. |
| 115 | 116 |
| 116 // Methods called by |ChannelEndpointClient|: | 117 // Methods called by |ChannelEndpointClient|: |
| 117 | 118 |
| 118 // Called to enqueue an outbound message. (If |AttachAndRun()| has not yet | 119 // Called to enqueue an outbound message. (If |AttachAndRun()| has not yet |
| 119 // been called, the message will be enqueued and sent when |AttachAndRun()| is | 120 // been called, the message will be enqueued and sent when |AttachAndRun()| is |
| 120 // called.) | 121 // called.) |
| 121 bool EnqueueMessage(std::unique_ptr<MessageInTransit> message); | 122 bool EnqueueMessage(std::unique_ptr<MessageInTransit> message); |
| 122 | 123 |
| 123 // Called to *replace* current client with a new client (which must differ | 124 // Called to *replace* current client with a new client (which must differ |
| 124 // from the existing client). This must not be called after | 125 // from the existing client). This must not be called after |
| 125 // |DetachFromClient()| has been called. | 126 // |DetachFromClient()| has been called. |
| 126 // | 127 // |
| 127 // This returns true in the typical case, and false if this endpoint has been | 128 // This returns true in the typical case, and false if this endpoint has been |
| 128 // detached from the channel, in which case the caller should probably call | 129 // detached from the channel, in which case the caller should probably call |
| 129 // its (new) client's |OnDetachFromChannel()|. | 130 // its (new) client's |OnDetachFromChannel()|. |
| 130 bool ReplaceClient(RefPtr<ChannelEndpointClient>&& client, | 131 bool ReplaceClient(util::RefPtr<ChannelEndpointClient>&& client, |
| 131 unsigned client_port); | 132 unsigned client_port); |
| 132 | 133 |
| 133 // Called before the |ChannelEndpointClient| gives up its reference to this | 134 // Called before the |ChannelEndpointClient| gives up its reference to this |
| 134 // object. | 135 // object. |
| 135 void DetachFromClient(); | 136 void DetachFromClient(); |
| 136 | 137 |
| 137 // Methods called by |Channel|: | 138 // Methods called by |Channel|: |
| 138 | 139 |
| 139 // Called when the |Channel| takes a reference to this object. This will send | 140 // Called when the |Channel| takes a reference to this object. This will send |
| 140 // all queue messages (in |channel_message_queue_|). | 141 // all queue messages (in |channel_message_queue_|). |
| (...skipping 13 matching lines...) Expand all Loading... |
| 154 FRIEND_MAKE_REF_COUNTED(ChannelEndpoint); | 155 FRIEND_MAKE_REF_COUNTED(ChannelEndpoint); |
| 155 | 156 |
| 156 // Constructor for a |ChannelEndpoint| with the given client (specified by | 157 // Constructor for a |ChannelEndpoint| with the given client (specified by |
| 157 // |client| and |client_port|). Optionally takes messages from | 158 // |client| and |client_port|). Optionally takes messages from |
| 158 // |*message_queue| if |message_queue| is non-null. | 159 // |*message_queue| if |message_queue| is non-null. |
| 159 // | 160 // |
| 160 // |client| may be null if this endpoint will never need to receive messages, | 161 // |client| may be null if this endpoint will never need to receive messages, |
| 161 // in which case |message_queue| should not be null. In that case, this | 162 // in which case |message_queue| should not be null. In that case, this |
| 162 // endpoint will simply send queued messages upon being attached to a | 163 // endpoint will simply send queued messages upon being attached to a |
| 163 // |Channel| and immediately detach itself. | 164 // |Channel| and immediately detach itself. |
| 164 ChannelEndpoint(RefPtr<ChannelEndpointClient>&& client, | 165 ChannelEndpoint(util::RefPtr<ChannelEndpointClient>&& client, |
| 165 unsigned client_port, | 166 unsigned client_port, |
| 166 MessageInTransitQueue* message_queue = nullptr); | 167 MessageInTransitQueue* message_queue = nullptr); |
| 167 | 168 |
| 168 ~ChannelEndpoint(); | 169 ~ChannelEndpoint(); |
| 169 | 170 |
| 170 bool WriteMessageNoLock(std::unique_ptr<MessageInTransit> message) | 171 bool WriteMessageNoLock(std::unique_ptr<MessageInTransit> message) |
| 171 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 172 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
| 172 | 173 |
| 173 // Helper for |OnReadMessage()|, handling messages for the client. | 174 // Helper for |OnReadMessage()|, handling messages for the client. |
| 174 void OnReadMessageForClient(std::unique_ptr<MessageInTransit> message); | 175 void OnReadMessageForClient(std::unique_ptr<MessageInTransit> message); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 185 // |AttachAndRun()| has been called, but not |DetachFromChannel()| | 186 // |AttachAndRun()| has been called, but not |DetachFromChannel()| |
| 186 // (|channel_| is non-null and valid). | 187 // (|channel_| is non-null and valid). |
| 187 RUNNING, | 188 RUNNING, |
| 188 // |DetachFromChannel()| has been called (|channel_| is null). | 189 // |DetachFromChannel()| has been called (|channel_| is null). |
| 189 DEAD | 190 DEAD |
| 190 }; | 191 }; |
| 191 State state_ MOJO_GUARDED_BY(mutex_); | 192 State state_ MOJO_GUARDED_BY(mutex_); |
| 192 | 193 |
| 193 // |client_| must be valid whenever it is non-null. Before |*client_| gives up | 194 // |client_| must be valid whenever it is non-null. Before |*client_| gives up |
| 194 // its reference to this object, it must call |DetachFromClient()|. | 195 // its reference to this object, it must call |DetachFromClient()|. |
| 195 // NOTE: This is a |RefPtr<>|, rather than a raw pointer, since the |Channel| | 196 // NOTE: This is a |util:RefPtr<>|, rather than a raw pointer, since the |
| 196 // needs to keep the client (e.g., |MessagePipe|) alive for the "proxy-proxy" | 197 // |Channel| needs to keep the client (e.g., |MessagePipe|) alive for the |
| 197 // case. | 198 // "proxy-proxy" case. |
| 198 // WARNING: |ChannelEndpointClient| methods must not be called under |mutex_|. | 199 // WARNING: |ChannelEndpointClient| methods must not be called under |mutex_|. |
| 199 // Thus to make such a call, a reference must first be taken under |mutex_| | 200 // Thus to make such a call, a reference must first be taken under |mutex_| |
| 200 // and the lock released. | 201 // and the lock released. |
| 201 // TODO(vtl): Annotate the above rule using |MOJO_ACQUIRED_{BEFORE,AFTER}()|, | 202 // TODO(vtl): Annotate the above rule using |MOJO_ACQUIRED_{BEFORE,AFTER}()|, |
| 202 // once clang actually checks such annotations. | 203 // once clang actually checks such annotations. |
| 203 // https://github.com/domokit/mojo/issues/313 | 204 // https://github.com/domokit/mojo/issues/313 |
| 204 // WARNING: Beware of interactions with |ReplaceClient()|. By the time the | 205 // WARNING: Beware of interactions with |ReplaceClient()|. By the time the |
| 205 // call is made, the client may have changed. This must be detected and dealt | 206 // call is made, the client may have changed. This must be detected and dealt |
| 206 // with. | 207 // with. |
| 207 RefPtr<ChannelEndpointClient> client_ MOJO_GUARDED_BY(mutex_); | 208 util::RefPtr<ChannelEndpointClient> client_ MOJO_GUARDED_BY(mutex_); |
| 208 unsigned client_port_ MOJO_GUARDED_BY(mutex_); | 209 unsigned client_port_ MOJO_GUARDED_BY(mutex_); |
| 209 | 210 |
| 210 // |channel_| must be valid whenever it is non-null. Before |*channel_| gives | 211 // |channel_| must be valid whenever it is non-null. Before |*channel_| gives |
| 211 // up its reference to this object, it must call |DetachFromChannel()|. | 212 // up its reference to this object, it must call |DetachFromChannel()|. |
| 212 // |local_id_| and |remote_id_| are valid if and only |channel_| is non-null. | 213 // |local_id_| and |remote_id_| are valid if and only |channel_| is non-null. |
| 213 Channel* channel_ MOJO_GUARDED_BY(mutex_); | 214 Channel* channel_ MOJO_GUARDED_BY(mutex_); |
| 214 ChannelEndpointId local_id_ MOJO_GUARDED_BY(mutex_); | 215 ChannelEndpointId local_id_ MOJO_GUARDED_BY(mutex_); |
| 215 ChannelEndpointId remote_id_ MOJO_GUARDED_BY(mutex_); | 216 ChannelEndpointId remote_id_ MOJO_GUARDED_BY(mutex_); |
| 216 | 217 |
| 217 // This queue is used before we're running on a channel and ready to send | 218 // This queue is used before we're running on a channel and ready to send |
| 218 // messages to the channel. | 219 // messages to the channel. |
| 219 MessageInTransitQueue channel_message_queue_ MOJO_GUARDED_BY(mutex_); | 220 MessageInTransitQueue channel_message_queue_ MOJO_GUARDED_BY(mutex_); |
| 220 | 221 |
| 221 MOJO_DISALLOW_COPY_AND_ASSIGN(ChannelEndpoint); | 222 MOJO_DISALLOW_COPY_AND_ASSIGN(ChannelEndpoint); |
| 222 }; | 223 }; |
| 223 | 224 |
| 224 } // namespace system | 225 } // namespace system |
| 225 } // namespace mojo | 226 } // namespace mojo |
| 226 | 227 |
| 227 #endif // MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_H_ | 228 #endif // MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_H_ |
| OLD | NEW |