Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: mojo/system/message_pipe.cc

Issue 259373003: Mojo: Minor cleanup (of message_in_transit.cc and message_pipe.*). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/system/message_pipe.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/system/message_pipe.h" 5 #include "mojo/system/message_pipe.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "mojo/system/channel.h" 8 #include "mojo/system/channel.h"
9 #include "mojo/system/local_message_pipe_endpoint.h" 9 #include "mojo/system/local_message_pipe_endpoint.h"
10 #include "mojo/system/message_in_transit.h" 10 #include "mojo/system/message_in_transit.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // TODO(vtl): Handle flags. 67 // TODO(vtl): Handle flags.
68 MojoResult MessagePipe::WriteMessage( 68 MojoResult MessagePipe::WriteMessage(
69 unsigned port, 69 unsigned port,
70 const void* bytes, 70 const void* bytes,
71 uint32_t num_bytes, 71 uint32_t num_bytes,
72 std::vector<DispatcherTransport>* transports, 72 std::vector<DispatcherTransport>* transports,
73 MojoWriteMessageFlags flags) { 73 MojoWriteMessageFlags flags) {
74 DCHECK(port == 0 || port == 1); 74 DCHECK(port == 0 || port == 1);
75 uint32_t num_handles = 75 uint32_t num_handles =
76 transports ? static_cast<uint32_t>(transports->size()) : 0; 76 transports ? static_cast<uint32_t>(transports->size()) : 0;
77 return EnqueueMessage( 77 return EnqueueMessageInternal(
78 GetPeerPort(port), 78 GetPeerPort(port),
79 make_scoped_ptr(new MessageInTransit( 79 make_scoped_ptr(new MessageInTransit(
80 MessageInTransit::kTypeMessagePipeEndpoint, 80 MessageInTransit::kTypeMessagePipeEndpoint,
81 MessageInTransit::kSubtypeMessagePipeEndpointData, 81 MessageInTransit::kSubtypeMessagePipeEndpointData,
82 num_bytes, num_handles, bytes)), 82 num_bytes, num_handles, bytes)),
83 transports); 83 transports);
84 } 84 }
85 85
86 MojoResult MessagePipe::ReadMessage( 86 MojoResult MessagePipe::ReadMessage(
87 unsigned port, 87 unsigned port,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 138
139 scoped_ptr<MessagePipeEndpoint> replacement_endpoint( 139 scoped_ptr<MessagePipeEndpoint> replacement_endpoint(
140 new ProxyMessagePipeEndpoint( 140 new ProxyMessagePipeEndpoint(
141 static_cast<LocalMessagePipeEndpoint*>(endpoints_[port].get()), 141 static_cast<LocalMessagePipeEndpoint*>(endpoints_[port].get()),
142 is_peer_open)); 142 is_peer_open));
143 endpoints_[port].swap(replacement_endpoint); 143 endpoints_[port].swap(replacement_endpoint);
144 } 144 }
145 145
146 MojoResult MessagePipe::EnqueueMessage( 146 MojoResult MessagePipe::EnqueueMessage(
147 unsigned port, 147 unsigned port,
148 scoped_ptr<MessageInTransit> message, 148 scoped_ptr<MessageInTransit> message) {
149 std::vector<DispatcherTransport>* transports) { 149 return EnqueueMessageInternal(port, message.Pass(), NULL);
150 DCHECK(port == 0 || port == 1);
151 DCHECK(message.get());
152 if (message->num_handles() == 0) {
153 // If |message->num_handles()| is 0, then |transports| should be null and
154 // |message| should not have dispatchers.
155 DCHECK(!transports);
156 DCHECK(!message->has_dispatchers());
157 } else {
158 // Otherwise either |transports| must be (non-null and) of the right size
159 // and the message shouldn't have dispatchers, or |transports| must be null
160 // and the message should have the right number of dispatchers.
161 DCHECK((transports && transports->size() == message->num_handles() &&
162 !message->has_dispatchers()) ||
163 (!transports && message->has_dispatchers() &&
164 message->dispatchers()->size() == message->num_handles()));
165 }
166
167 if (message->type() == MessageInTransit::kTypeMessagePipe) {
168 DCHECK(!transports);
169 return HandleControlMessage(port, message.Pass());
170 }
171
172 DCHECK_EQ(message->type(), MessageInTransit::kTypeMessagePipeEndpoint);
173
174 base::AutoLock locker(lock_);
175 DCHECK(endpoints_[GetPeerPort(port)].get());
176
177 // The destination port need not be open, unlike the source port.
178 if (!endpoints_[port].get())
179 return MOJO_RESULT_FAILED_PRECONDITION;
180
181 if (transports) {
182 DCHECK(!message->dispatchers());
183
184 // You're not allowed to send either handle to a message pipe over the
185 // message pipe, so check for this. (The case of trying to write a handle to
186 // itself is taken care of by |Core|. That case kind of makes sense, but
187 // leads to complications if, e.g., both sides try to do the same thing with
188 // their respective handles simultaneously. The other case, of trying to
189 // write the peer handle to a handle, doesn't make sense -- since no handle
190 // will be available to read the message from.)
191 for (size_t i = 0; i < transports->size(); i++) {
192 if (!(*transports)[i].is_valid())
193 continue;
194 if ((*transports)[i].GetType() == Dispatcher::kTypeMessagePipe) {
195 MessagePipeDispatcherTransport mp_transport((*transports)[i]);
196 if (mp_transport.GetMessagePipe() == this) {
197 // The other case should have been disallowed by |Core|. (Note: |port|
198 // is the peer port of the handle given to |WriteMessage()|.)
199 DCHECK_EQ(mp_transport.GetPort(), port);
200 return MOJO_RESULT_INVALID_ARGUMENT;
201 }
202 }
203 }
204
205 // Clone the dispatchers and attach them to the message. (This must be done
206 // as a separate loop, since we want to leave the dispatchers alone on
207 // failure.)
208 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > >
209 dispatchers(new std::vector<scoped_refptr<Dispatcher> >());
210 dispatchers->reserve(transports->size());
211 for (size_t i = 0; i < transports->size(); i++) {
212 if ((*transports)[i].is_valid()) {
213 dispatchers->push_back(
214 (*transports)[i].CreateEquivalentDispatcherAndClose());
215 } else {
216 LOG(WARNING) << "Enqueueing null dispatcher";
217 dispatchers->push_back(scoped_refptr<Dispatcher>());
218 }
219 }
220 message->SetDispatchers(dispatchers.Pass());
221 }
222
223 // The endpoint's |EnqueueMessage()| may not report failure.
224 endpoints_[port]->EnqueueMessage(message.Pass());
225 return MOJO_RESULT_OK;
226 } 150 }
227 151
228 bool MessagePipe::Attach(unsigned port, 152 bool MessagePipe::Attach(unsigned port,
229 scoped_refptr<Channel> channel, 153 scoped_refptr<Channel> channel,
230 MessageInTransit::EndpointId local_id) { 154 MessageInTransit::EndpointId local_id) {
231 DCHECK(port == 0 || port == 1); 155 DCHECK(port == 0 || port == 1);
232 DCHECK(channel.get()); 156 DCHECK(channel.get());
233 DCHECK_NE(local_id, MessageInTransit::kInvalidEndpointId); 157 DCHECK_NE(local_id, MessageInTransit::kInvalidEndpointId);
234 158
235 base::AutoLock locker(lock_); 159 base::AutoLock locker(lock_);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } 192 }
269 193
270 MessagePipe::~MessagePipe() { 194 MessagePipe::~MessagePipe() {
271 // Owned by the dispatchers. The owning dispatchers should only release us via 195 // Owned by the dispatchers. The owning dispatchers should only release us via
272 // their |Close()| method, which should inform us of being closed via our 196 // their |Close()| method, which should inform us of being closed via our
273 // |Close()|. Thus these should already be null. 197 // |Close()|. Thus these should already be null.
274 DCHECK(!endpoints_[0].get()); 198 DCHECK(!endpoints_[0].get());
275 DCHECK(!endpoints_[1].get()); 199 DCHECK(!endpoints_[1].get());
276 } 200 }
277 201
202 MojoResult MessagePipe::EnqueueMessageInternal(
203 unsigned port,
204 scoped_ptr<MessageInTransit> message,
205 std::vector<DispatcherTransport>* transports) {
206 DCHECK(port == 0 || port == 1);
207 DCHECK(message.get());
208
209 if (message->type() == MessageInTransit::kTypeMessagePipe) {
210 DCHECK(!transports);
211 return HandleControlMessage(port, message.Pass());
212 }
213
214 DCHECK_EQ(message->type(), MessageInTransit::kTypeMessagePipeEndpoint);
215
216 base::AutoLock locker(lock_);
217 DCHECK(endpoints_[GetPeerPort(port)].get());
218
219 // The destination port need not be open, unlike the source port.
220 if (!endpoints_[port].get())
221 return MOJO_RESULT_FAILED_PRECONDITION;
222
223 if (transports) {
224 MojoResult result = AttachTransportsNoLock(port, message.get(), transports);
225 if (result != MOJO_RESULT_OK)
226 return result;
227 }
228
229 if (message->has_dispatchers())
230 DCHECK_EQ(message->dispatchers()->size(), message->num_handles());
231
232 // The endpoint's |EnqueueMessage()| may not report failure.
233 endpoints_[port]->EnqueueMessage(message.Pass());
234 return MOJO_RESULT_OK;
235 }
236
237 MojoResult MessagePipe::AttachTransportsNoLock(
238 unsigned port,
239 MessageInTransit* message,
240 std::vector<DispatcherTransport>* transports) {
241 DCHECK(!message->has_dispatchers());
242 DCHECK_EQ(transports->size(), message->num_handles());
243
244 // You're not allowed to send either handle to a message pipe over the message
245 // pipe, so check for this. (The case of trying to write a handle to itself is
246 // taken care of by |Core|. That case kind of makes sense, but leads to
247 // complications if, e.g., both sides try to do the same thing with their
248 // respective handles simultaneously. The other case, of trying to write the
249 // peer handle to a handle, doesn't make sense -- since no handle will be
250 // available to read the message from.)
251 for (size_t i = 0; i < transports->size(); i++) {
252 if (!(*transports)[i].is_valid())
253 continue;
254 if ((*transports)[i].GetType() == Dispatcher::kTypeMessagePipe) {
255 MessagePipeDispatcherTransport mp_transport((*transports)[i]);
256 if (mp_transport.GetMessagePipe() == this) {
257 // The other case should have been disallowed by |Core|. (Note: |port|
258 // is the peer port of the handle given to |WriteMessage()|.)
259 DCHECK_EQ(mp_transport.GetPort(), port);
260 return MOJO_RESULT_INVALID_ARGUMENT;
261 }
262 }
263 }
264
265 // Clone the dispatchers and attach them to the message. (This must be done as
266 // a separate loop, since we want to leave the dispatchers alone on failure.)
267 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > >
268 dispatchers(new std::vector<scoped_refptr<Dispatcher> >());
269 dispatchers->reserve(transports->size());
270 for (size_t i = 0; i < transports->size(); i++) {
271 if ((*transports)[i].is_valid()) {
272 dispatchers->push_back(
273 (*transports)[i].CreateEquivalentDispatcherAndClose());
274 } else {
275 LOG(WARNING) << "Enqueueing null dispatcher";
276 dispatchers->push_back(scoped_refptr<Dispatcher>());
277 }
278 }
279 message->SetDispatchers(dispatchers.Pass());
280 return MOJO_RESULT_OK;
281 }
282
278 MojoResult MessagePipe::HandleControlMessage( 283 MojoResult MessagePipe::HandleControlMessage(
279 unsigned /*port*/, 284 unsigned /*port*/,
280 scoped_ptr<MessageInTransit> message) { 285 scoped_ptr<MessageInTransit> message) {
281 LOG(WARNING) << "Unrecognized MessagePipe control message subtype " 286 LOG(WARNING) << "Unrecognized MessagePipe control message subtype "
282 << message->subtype(); 287 << message->subtype();
283 return MOJO_RESULT_UNKNOWN; 288 return MOJO_RESULT_UNKNOWN;
284 } 289 }
285 290
286 } // namespace system 291 } // namespace system
287 } // namespace mojo 292 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/message_pipe.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698