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 #include "mojo/edk/system/message_pipe_dispatcher.h" | 5 #include "mojo/edk/system/message_pipe_dispatcher.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "mojo/edk/system/channel.h" | 8 #include "mojo/edk/system/configuration.h" |
9 #include "mojo/edk/system/channel_endpoint.h" | |
10 #include "mojo/edk/system/channel_endpoint_id.h" | |
11 #include "mojo/edk/system/constants.h" | |
12 #include "mojo/edk/system/local_message_pipe_endpoint.h" | 9 #include "mojo/edk/system/local_message_pipe_endpoint.h" |
13 #include "mojo/edk/system/memory.h" | 10 #include "mojo/edk/system/memory.h" |
14 #include "mojo/edk/system/message_pipe.h" | 11 #include "mojo/edk/system/message_pipe.h" |
15 #include "mojo/edk/system/options_validation.h" | 12 #include "mojo/edk/system/options_validation.h" |
16 #include "mojo/edk/system/proxy_message_pipe_endpoint.h" | 13 #include "mojo/edk/system/proxy_message_pipe_endpoint.h" |
17 | 14 |
18 namespace mojo { | 15 namespace mojo { |
19 namespace system { | 16 namespace system { |
20 | 17 |
21 namespace { | |
22 | |
23 const unsigned kInvalidPort = static_cast<unsigned>(-1); | 18 const unsigned kInvalidPort = static_cast<unsigned>(-1); |
24 | 19 |
25 struct SerializedMessagePipeDispatcher { | |
26 // This is the endpoint ID on the receiving side, and should be a "remote ID". | |
27 // (The receiving side should have already have an endpoint attached and run | |
28 // via the |Channel|s. This endpoint will have both IDs assigned, so this ID | |
29 // is only needed to associated that endpoint with a particular dispatcher.) | |
30 ChannelEndpointId receiver_endpoint_id; | |
31 }; | |
32 | |
33 } // namespace | |
34 | |
35 // MessagePipeDispatcher ------------------------------------------------------- | 20 // MessagePipeDispatcher ------------------------------------------------------- |
36 | 21 |
37 // static | 22 // static |
38 const MojoCreateMessagePipeOptions | 23 const MojoCreateMessagePipeOptions |
39 MessagePipeDispatcher::kDefaultCreateOptions = { | 24 MessagePipeDispatcher::kDefaultCreateOptions = { |
40 static_cast<uint32_t>(sizeof(MojoCreateMessagePipeOptions)), | 25 static_cast<uint32_t>(sizeof(MojoCreateMessagePipeOptions)), |
41 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE}; | 26 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE}; |
42 | 27 |
43 MessagePipeDispatcher::MessagePipeDispatcher( | 28 MessagePipeDispatcher::MessagePipeDispatcher( |
44 const MojoCreateMessagePipeOptions& /*validated_options*/) | 29 const MojoCreateMessagePipeOptions& /*validated_options*/) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); | 81 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); |
97 dispatcher->Init(message_pipe, 0); | 82 dispatcher->Init(message_pipe, 0); |
98 return dispatcher; | 83 return dispatcher; |
99 } | 84 } |
100 | 85 |
101 // static | 86 // static |
102 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( | 87 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( |
103 Channel* channel, | 88 Channel* channel, |
104 const void* source, | 89 const void* source, |
105 size_t size) { | 90 size_t size) { |
106 if (size != sizeof(SerializedMessagePipeDispatcher)) { | 91 unsigned port = kInvalidPort; |
107 LOG(ERROR) << "Invalid serialized message pipe dispatcher"; | 92 scoped_refptr<MessagePipe> message_pipe; |
108 return scoped_refptr<MessagePipeDispatcher>(); | 93 if (!MessagePipe::Deserialize(channel, source, size, &message_pipe, &port)) |
109 } | 94 return nullptr; |
| 95 DCHECK(message_pipe.get()); |
| 96 DCHECK(port == 0 || port == 1); |
110 | 97 |
111 const SerializedMessagePipeDispatcher* s = | |
112 static_cast<const SerializedMessagePipeDispatcher*>(source); | |
113 scoped_refptr<MessagePipe> message_pipe = | |
114 channel->PassIncomingMessagePipe(s->receiver_endpoint_id); | |
115 if (!message_pipe.get()) { | |
116 LOG(ERROR) << "Failed to deserialize message pipe dispatcher (ID = " | |
117 << s->receiver_endpoint_id << ")"; | |
118 return scoped_refptr<MessagePipeDispatcher>(); | |
119 } | |
120 | |
121 DVLOG(2) << "Deserializing message pipe dispatcher (new local ID = " | |
122 << s->receiver_endpoint_id << ")"; | |
123 scoped_refptr<MessagePipeDispatcher> dispatcher( | 98 scoped_refptr<MessagePipeDispatcher> dispatcher( |
124 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); | 99 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); |
125 dispatcher->Init(message_pipe, 0); | 100 dispatcher->Init(message_pipe, port); |
126 return dispatcher; | 101 return dispatcher; |
127 } | 102 } |
128 | 103 |
129 MessagePipeDispatcher::~MessagePipeDispatcher() { | 104 MessagePipeDispatcher::~MessagePipeDispatcher() { |
130 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. | 105 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. |
131 DCHECK(!message_pipe_.get()); | 106 DCHECK(!message_pipe_.get()); |
132 } | 107 } |
133 | 108 |
134 MessagePipe* MessagePipeDispatcher::GetMessagePipeNoLock() const { | 109 MessagePipe* MessagePipeDispatcher::GetMessagePipeNoLock() const { |
135 lock().AssertAcquired(); | 110 lock().AssertAcquired(); |
(...skipping 30 matching lines...) Expand all Loading... |
166 message_pipe_ = nullptr; | 141 message_pipe_ = nullptr; |
167 port_ = kInvalidPort; | 142 port_ = kInvalidPort; |
168 return scoped_refptr<Dispatcher>(rv.get()); | 143 return scoped_refptr<Dispatcher>(rv.get()); |
169 } | 144 } |
170 | 145 |
171 MojoResult MessagePipeDispatcher::WriteMessageImplNoLock( | 146 MojoResult MessagePipeDispatcher::WriteMessageImplNoLock( |
172 UserPointer<const void> bytes, | 147 UserPointer<const void> bytes, |
173 uint32_t num_bytes, | 148 uint32_t num_bytes, |
174 std::vector<DispatcherTransport>* transports, | 149 std::vector<DispatcherTransport>* transports, |
175 MojoWriteMessageFlags flags) { | 150 MojoWriteMessageFlags flags) { |
176 DCHECK(!transports || (transports->size() > 0 && | 151 DCHECK(!transports || |
177 transports->size() <= kMaxMessageNumHandles)); | 152 (transports->size() > 0 && |
| 153 transports->size() <= GetConfiguration().max_message_num_handles)); |
178 | 154 |
179 lock().AssertAcquired(); | 155 lock().AssertAcquired(); |
180 | 156 |
181 if (num_bytes > kMaxMessageNumBytes) | 157 if (num_bytes > GetConfiguration().max_message_num_bytes) |
182 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 158 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
183 | 159 |
184 return message_pipe_->WriteMessage( | 160 return message_pipe_->WriteMessage(port_, bytes, num_bytes, transports, |
185 port_, bytes, num_bytes, transports, flags); | 161 flags); |
186 } | 162 } |
187 | 163 |
188 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( | 164 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( |
189 UserPointer<void> bytes, | 165 UserPointer<void> bytes, |
190 UserPointer<uint32_t> num_bytes, | 166 UserPointer<uint32_t> num_bytes, |
191 DispatcherVector* dispatchers, | 167 DispatcherVector* dispatchers, |
192 uint32_t* num_dispatchers, | 168 uint32_t* num_dispatchers, |
193 MojoReadMessageFlags flags) { | 169 MojoReadMessageFlags flags) { |
194 lock().AssertAcquired(); | 170 lock().AssertAcquired(); |
195 return message_pipe_->ReadMessage( | 171 return message_pipe_->ReadMessage(port_, bytes, num_bytes, dispatchers, |
196 port_, bytes, num_bytes, dispatchers, num_dispatchers, flags); | 172 num_dispatchers, flags); |
197 } | 173 } |
198 | 174 |
199 HandleSignalsState MessagePipeDispatcher::GetHandleSignalsStateImplNoLock() | 175 HandleSignalsState MessagePipeDispatcher::GetHandleSignalsStateImplNoLock() |
200 const { | 176 const { |
201 lock().AssertAcquired(); | 177 lock().AssertAcquired(); |
202 return message_pipe_->GetHandleSignalsState(port_); | 178 return message_pipe_->GetHandleSignalsState(port_); |
203 } | 179 } |
204 | 180 |
205 MojoResult MessagePipeDispatcher::AddWaiterImplNoLock( | 181 MojoResult MessagePipeDispatcher::AddWaiterImplNoLock( |
206 Waiter* waiter, | 182 Waiter* waiter, |
207 MojoHandleSignals signals, | 183 MojoHandleSignals signals, |
208 uint32_t context, | 184 uint32_t context, |
209 HandleSignalsState* signals_state) { | 185 HandleSignalsState* signals_state) { |
210 lock().AssertAcquired(); | 186 lock().AssertAcquired(); |
211 return message_pipe_->AddWaiter( | 187 return message_pipe_->AddWaiter(port_, waiter, signals, context, |
212 port_, waiter, signals, context, signals_state); | 188 signals_state); |
213 } | 189 } |
214 | 190 |
215 void MessagePipeDispatcher::RemoveWaiterImplNoLock( | 191 void MessagePipeDispatcher::RemoveWaiterImplNoLock( |
216 Waiter* waiter, | 192 Waiter* waiter, |
217 HandleSignalsState* signals_state) { | 193 HandleSignalsState* signals_state) { |
218 lock().AssertAcquired(); | 194 lock().AssertAcquired(); |
219 message_pipe_->RemoveWaiter(port_, waiter, signals_state); | 195 message_pipe_->RemoveWaiter(port_, waiter, signals_state); |
220 } | 196 } |
221 | 197 |
222 void MessagePipeDispatcher::StartSerializeImplNoLock( | 198 void MessagePipeDispatcher::StartSerializeImplNoLock( |
223 Channel* /*channel*/, | 199 Channel* channel, |
224 size_t* max_size, | 200 size_t* max_size, |
225 size_t* max_platform_handles) { | 201 size_t* max_platform_handles) { |
226 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 202 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
227 *max_size = sizeof(SerializedMessagePipeDispatcher); | 203 return message_pipe_->StartSerialize(port_, channel, max_size, |
228 *max_platform_handles = 0; | 204 max_platform_handles); |
229 } | 205 } |
230 | 206 |
231 bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock( | 207 bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock( |
232 Channel* channel, | 208 Channel* channel, |
233 void* destination, | 209 void* destination, |
234 size_t* actual_size, | 210 size_t* actual_size, |
235 embedder::PlatformHandleVector* /*platform_handles*/) { | 211 embedder::PlatformHandleVector* platform_handles) { |
236 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 212 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
237 | 213 |
238 SerializedMessagePipeDispatcher* s = | 214 bool rv = message_pipe_->EndSerialize(port_, channel, destination, |
239 static_cast<SerializedMessagePipeDispatcher*>(destination); | 215 actual_size, platform_handles); |
240 | |
241 // Convert the local endpoint to a proxy endpoint (moving the message queue) | |
242 // and attach it to the channel. | |
243 s->receiver_endpoint_id = channel->AttachAndRunEndpoint( | |
244 message_pipe_->ConvertLocalToProxy(port_), false); | |
245 DVLOG(2) << "Serializing message pipe dispatcher (remote ID = " | |
246 << s->receiver_endpoint_id << ")"; | |
247 | |
248 message_pipe_ = nullptr; | 216 message_pipe_ = nullptr; |
249 port_ = kInvalidPort; | 217 port_ = kInvalidPort; |
250 | 218 return rv; |
251 *actual_size = sizeof(SerializedMessagePipeDispatcher); | |
252 return true; | |
253 } | 219 } |
254 | 220 |
255 // MessagePipeDispatcherTransport ---------------------------------------------- | 221 // MessagePipeDispatcherTransport ---------------------------------------------- |
256 | 222 |
257 MessagePipeDispatcherTransport::MessagePipeDispatcherTransport( | 223 MessagePipeDispatcherTransport::MessagePipeDispatcherTransport( |
258 DispatcherTransport transport) | 224 DispatcherTransport transport) |
259 : DispatcherTransport(transport) { | 225 : DispatcherTransport(transport) { |
260 DCHECK_EQ(message_pipe_dispatcher()->GetType(), Dispatcher::kTypeMessagePipe); | 226 DCHECK_EQ(message_pipe_dispatcher()->GetType(), Dispatcher::kTypeMessagePipe); |
261 } | 227 } |
262 | 228 |
263 } // namespace system | 229 } // namespace system |
264 } // namespace mojo | 230 } // namespace mojo |
OLD | NEW |