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/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 65 |
66 // This must be called on the creation thread before destruction (which can | 66 // This must be called on the creation thread before destruction (which can |
67 // happen on any thread). | 67 // happen on any thread). |
68 void Shutdown(); | 68 void Shutdown(); |
69 | 69 |
70 // Attaches the given message pipe/port's endpoint (which must be a | 70 // Attaches the given message pipe/port's endpoint (which must be a |
71 // |ProxyMessagePipeEndpoint|) to this channel. This assigns it a local ID, | 71 // |ProxyMessagePipeEndpoint|) to this channel. This assigns it a local ID, |
72 // which it returns. The first message pipe endpoint attached will always have | 72 // which it returns. The first message pipe endpoint attached will always have |
73 // |kBootstrapEndpointId| as its local ID. (For bootstrapping, this occurs on | 73 // |kBootstrapEndpointId| as its local ID. (For bootstrapping, this occurs on |
74 // both sides, so one should use |kBootstrapEndpointId| for the remote ID for | 74 // both sides, so one should use |kBootstrapEndpointId| for the remote ID for |
75 // the first message pipe across a channel.) | 75 // the first message pipe across a channel.) Returns |kInvalidEndpointId| on |
76 // TODO(vtl): Maybe limit the number of attached message pipes and allow this | 76 // failure. |
77 // to fail. | 77 // TODO(vtl): Maybe limit the number of attached message pipes. |
78 MessageInTransit::EndpointId AttachMessagePipeEndpoint( | 78 MessageInTransit::EndpointId AttachMessagePipeEndpoint( |
79 scoped_refptr<MessagePipe> message_pipe, unsigned port); | 79 scoped_refptr<MessagePipe> message_pipe, |
| 80 unsigned port); |
80 | 81 |
81 // Runs the message pipe with the given |local_id| (previously attached), with | 82 // Runs the message pipe with the given |local_id| (previously attached), with |
82 // the given |remote_id| (negotiated using some other means, e.g., over an | 83 // the given |remote_id| (negotiated using some other means, e.g., over an |
83 // existing message pipe; see comments above for the bootstrap case). Returns | 84 // existing message pipe; see comments above for the bootstrap case). Returns |
84 // false on failure, in particular if no message pipe with |local_id| is | 85 // false on failure, in particular if no message pipe with |local_id| is |
85 // attached. | 86 // attached. |
86 bool RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id, | 87 bool RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id, |
87 MessageInTransit::EndpointId remote_id); | 88 MessageInTransit::EndpointId remote_id); |
88 | 89 |
89 // Tells the other side of the channel to run a message pipe endpoint (which | 90 // Tells the other side of the channel to run a message pipe endpoint (which |
90 // must already be attached); |local_id| and |remote_id| are relative to this | 91 // must already be attached); |local_id| and |remote_id| are relative to this |
91 // channel (i.e., |local_id| is the other side's remote ID and |remote_id| is | 92 // channel (i.e., |local_id| is the other side's remote ID and |remote_id| is |
92 // its local ID). | 93 // its local ID). |
93 // TODO(vtl): Maybe we should just have a flag argument to | 94 // TODO(vtl): Maybe we should just have a flag argument to |
94 // |RunMessagePipeEndpoint()| that tells it to do this. | 95 // |RunMessagePipeEndpoint()| that tells it to do this. |
95 void RunRemoteMessagePipeEndpoint(MessageInTransit::EndpointId local_id, | 96 void RunRemoteMessagePipeEndpoint(MessageInTransit::EndpointId local_id, |
96 MessageInTransit::EndpointId remote_id); | 97 MessageInTransit::EndpointId remote_id); |
97 | 98 |
98 // This forwards |message| verbatim to |raw_channel_|. | 99 // This forwards |message| verbatim to |raw_channel_|. |
99 bool WriteMessage(scoped_ptr<MessageInTransit> message); | 100 bool WriteMessage(scoped_ptr<MessageInTransit> message); |
100 | 101 |
101 // See |RawChannel::IsWriteBufferEmpty()|. | 102 // See |RawChannel::IsWriteBufferEmpty()|. |
102 // TODO(vtl): Maybe we shouldn't expose this, and instead have a | 103 // TODO(vtl): Maybe we shouldn't expose this, and instead have a |
103 // |FlushWriteBufferAndShutdown()| or something like that. | 104 // |FlushWriteBufferAndShutdown()| or something like that. |
104 bool IsWriteBufferEmpty(); | 105 bool IsWriteBufferEmpty(); |
105 | 106 |
106 // This removes the message pipe/port's endpoint (with the given local ID, | 107 // This removes the message pipe/port's endpoint (with the given local ID and |
| 108 // given remote ID, which should be |kInvalidEndpointId| if not yet running), |
107 // returned by |AttachMessagePipeEndpoint()| from this channel. After this is | 109 // returned by |AttachMessagePipeEndpoint()| from this channel. After this is |
108 // called, |local_id| may be reused for another message pipe. | 110 // called, |local_id| may be reused for another message pipe. |
109 void DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id); | 111 void DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id, |
| 112 MessageInTransit::EndpointId remote_id); |
110 | 113 |
111 private: | 114 private: |
112 friend class base::RefCountedThreadSafe<Channel>; | 115 friend class base::RefCountedThreadSafe<Channel>; |
113 virtual ~Channel(); | 116 virtual ~Channel(); |
114 | 117 |
115 // |RawChannel::Delegate| implementation: | 118 // |RawChannel::Delegate| implementation: |
116 virtual void OnReadMessage( | 119 virtual void OnReadMessage( |
117 const MessageInTransit::View& message_view) OVERRIDE; | 120 const MessageInTransit::View& message_view) OVERRIDE; |
118 virtual void OnFatalError(FatalError fatal_error) OVERRIDE; | 121 virtual void OnFatalError(FatalError fatal_error) OVERRIDE; |
119 | 122 |
120 // Helpers for |OnReadMessage|: | 123 // Helpers for |OnReadMessage|: |
121 bool ValidateReadMessage(const MessageInTransit::View& message_view); | 124 bool ValidateReadMessage(const MessageInTransit::View& message_view); |
122 void OnReadMessageForDownstream(const MessageInTransit::View& message_view); | 125 void OnReadMessageForDownstream(const MessageInTransit::View& message_view); |
123 void OnReadMessageForChannel(const MessageInTransit::View& message_view); | 126 void OnReadMessageForChannel(const MessageInTransit::View& message_view); |
124 | 127 |
| 128 // Removes the message pipe endpoint with the given local ID, which must exist |
| 129 // and be a zombie, and given remote ID. Returns false on failure, in |
| 130 // particular if no message pipe with |local_id| is attached. |
| 131 bool RemoveMessagePipeEndpoint(MessageInTransit::EndpointId local_id, |
| 132 MessageInTransit::EndpointId remote_id); |
| 133 |
125 // Handles errors (e.g., invalid messages) from the remote side. | 134 // Handles errors (e.g., invalid messages) from the remote side. |
126 void HandleRemoteError(const base::StringPiece& error_message); | 135 void HandleRemoteError(const base::StringPiece& error_message); |
127 // Handles internal errors/failures from the local side. | 136 // Handles internal errors/failures from the local side. |
128 void HandleLocalError(const base::StringPiece& error_message); | 137 void HandleLocalError(const base::StringPiece& error_message); |
129 | 138 |
| 139 // Helper to send channel control messages. Returns true on success. Should be |
| 140 // called *without* |lock_| held. |
| 141 bool SendControlMessage(MessageInTransit::Subtype subtype, |
| 142 MessageInTransit::EndpointId source_id, |
| 143 MessageInTransit::EndpointId destination_id); |
| 144 |
130 struct EndpointInfo { | 145 struct EndpointInfo { |
| 146 enum State { |
| 147 // Attached, possibly running or not. |
| 148 STATE_NORMAL, |
| 149 // "Zombie" states: |
| 150 // Waiting for |DetachMessagePipeEndpoint()| before removing. |
| 151 STATE_WAIT_LOCAL_DETACH, |
| 152 // Waiting for a |kSubtypeChannelRemoveMessagePipeEndpointAck| before |
| 153 // removing. |
| 154 STATE_WAIT_REMOTE_REMOVE_ACK, |
| 155 // Waiting for both of the above conditions before removing. |
| 156 STATE_WAIT_LOCAL_DETACH_AND_REMOTE_REMOVE_ACK, |
| 157 }; |
| 158 |
131 EndpointInfo(); | 159 EndpointInfo(); |
132 EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port); | 160 EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port); |
133 ~EndpointInfo(); | 161 ~EndpointInfo(); |
134 | 162 |
| 163 State state; |
135 scoped_refptr<MessagePipe> message_pipe; | 164 scoped_refptr<MessagePipe> message_pipe; |
136 unsigned port; | 165 unsigned port; |
137 }; | 166 }; |
138 | 167 |
139 base::ThreadChecker creation_thread_checker_; | 168 base::ThreadChecker creation_thread_checker_; |
140 | 169 |
141 // Note: |MessagePipe|s MUST NOT be used under |lock_|. I.e., |lock_| can only | 170 // Note: |MessagePipe|s MUST NOT be used under |lock_|. I.e., |lock_| can only |
142 // be acquired after |MessagePipe::lock_|, never before. Thus to call into a | 171 // be acquired after |MessagePipe::lock_|, never before. Thus to call into a |
143 // |MessagePipe|, a reference should be acquired from | 172 // |MessagePipe|, a reference should be acquired from |
144 // |local_id_to_endpoint_info_map_| under |lock_| (e.g., by copying the | 173 // |local_id_to_endpoint_info_map_| under |lock_| (e.g., by copying the |
145 // |EndpointInfo|) and then the lock released. | 174 // |EndpointInfo|) and then the lock released. |
146 base::Lock lock_; // Protects the members below. | 175 base::Lock lock_; // Protects the members below. |
147 | 176 |
148 scoped_ptr<RawChannel> raw_channel_; | 177 scoped_ptr<RawChannel> raw_channel_; |
149 | 178 |
150 typedef base::hash_map<MessageInTransit::EndpointId, EndpointInfo> | 179 typedef base::hash_map<MessageInTransit::EndpointId, EndpointInfo> |
151 IdToEndpointInfoMap; | 180 IdToEndpointInfoMap; |
152 IdToEndpointInfoMap local_id_to_endpoint_info_map_; | 181 IdToEndpointInfoMap local_id_to_endpoint_info_map_; |
153 // The next local ID to try (when allocating new local IDs). Note: It should | 182 // The next local ID to try (when allocating new local IDs). Note: It should |
154 // be checked for existence before use. | 183 // be checked for existence before use. |
155 MessageInTransit::EndpointId next_local_id_; | 184 MessageInTransit::EndpointId next_local_id_; |
156 | 185 |
157 DISALLOW_COPY_AND_ASSIGN(Channel); | 186 DISALLOW_COPY_AND_ASSIGN(Channel); |
158 }; | 187 }; |
159 | 188 |
160 } // namespace system | 189 } // namespace system |
161 } // namespace mojo | 190 } // namespace mojo |
162 | 191 |
163 #endif // MOJO_SYSTEM_CHANNEL_H_ | 192 #endif // MOJO_SYSTEM_CHANNEL_H_ |
OLD | NEW |