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

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

Issue 1943123002: Make it possible to write a message pipe endpoint's peer into it. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 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
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/edk/system/message_pipe.h" 5 #include "mojo/edk/system/message_pipe.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 117
118 MessagePipeEndpoint::Type MessagePipe::GetType(unsigned port) { 118 MessagePipeEndpoint::Type MessagePipe::GetType(unsigned port) {
119 DCHECK(port == 0 || port == 1); 119 DCHECK(port == 0 || port == 1);
120 MutexLocker locker(&mutex_); 120 MutexLocker locker(&mutex_);
121 DCHECK(endpoints_[port]); 121 DCHECK(endpoints_[port]);
122 122
123 return endpoints_[port]->GetType(); 123 return endpoints_[port]->GetType();
124 } 124 }
125 125
126 void MessagePipe::CancelAllAwakables(unsigned port) { 126 void MessagePipe::CancelAllAwakables(unsigned port) {
127 DCHECK(port == 0 || port == 1);
128
129 MutexLocker locker(&mutex_); 127 MutexLocker locker(&mutex_);
130 DCHECK(endpoints_[port]); 128 CancelAllAwakablesNoLock(port);
131 endpoints_[port]->CancelAllAwakables();
132 } 129 }
133 130
134 void MessagePipe::Close(unsigned port) { 131 void MessagePipe::Close(unsigned port) {
135 DCHECK(port == 0 || port == 1); 132 DCHECK(port == 0 || port == 1);
136 133
137 unsigned peer_port = GetPeerPort(port); 134 unsigned peer_port = GetPeerPort(port);
138 135
139 MutexLocker locker(&mutex_); 136 MutexLocker locker(&mutex_);
140 // The endpoint's |OnPeerClose()| may have been called first and returned 137 // The endpoint's |OnPeerClose()| may have been called first and returned
141 // false, which would have resulted in its destruction. 138 // false, which would have resulted in its destruction.
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 endpoints_[peer_port].reset(); 276 endpoints_[peer_port].reset();
280 } 277 }
281 278
282 endpoints_[port]->Close(); 279 endpoints_[port]->Close();
283 endpoints_[port].reset(replacement_endpoint); 280 endpoints_[port].reset(replacement_endpoint);
284 281
285 *actual_size = channel->GetSerializedEndpointSize(); 282 *actual_size = channel->GetSerializedEndpointSize();
286 return true; 283 return true;
287 } 284 }
288 285
286 void MessagePipe::CancelAllAwakablesNoLock(unsigned port) {
287 DCHECK(port == 0 || port == 1);
288 mutex_.AssertHeld();
289 DCHECK(endpoints_[port]);
290 endpoints_[port]->CancelAllAwakables();
291 }
292
289 bool MessagePipe::OnReadMessage(unsigned port, MessageInTransit* message) { 293 bool MessagePipe::OnReadMessage(unsigned port, MessageInTransit* message) {
290 MutexLocker locker(&mutex_); 294 MutexLocker locker(&mutex_);
291 295
292 if (!endpoints_[port]) { 296 if (!endpoints_[port]) {
293 // This will happen only on the rare occasion that the call to 297 // This will happen only on the rare occasion that the call to
294 // |OnReadMessage()| is racing with us calling 298 // |OnReadMessage()| is racing with us calling
295 // |ChannelEndpoint::ReplaceClient()|, in which case we reject the message, 299 // |ChannelEndpoint::ReplaceClient()|, in which case we reject the message,
296 // and the |ChannelEndpoint| can retry (calling the new client's 300 // and the |ChannelEndpoint| can retry (calling the new client's
297 // |OnReadMessage()|). 301 // |OnReadMessage()|).
298 return false; 302 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 endpoints_[port]->EnqueueMessage(std::move(message)); 352 endpoints_[port]->EnqueueMessage(std::move(message));
349 return MOJO_RESULT_OK; 353 return MOJO_RESULT_OK;
350 } 354 }
351 355
352 MojoResult MessagePipe::AttachTransportsNoLock( 356 MojoResult MessagePipe::AttachTransportsNoLock(
353 unsigned port, 357 unsigned port,
354 MessageInTransit* message, 358 MessageInTransit* message,
355 std::vector<DispatcherTransport>* transports) { 359 std::vector<DispatcherTransport>* transports) {
356 DCHECK(!message->has_dispatchers()); 360 DCHECK(!message->has_dispatchers());
357 361
358 // You're not allowed to send either handle to a message pipe over the message
359 // pipe, so check for this. (The case of trying to write a handle to itself is
360 // taken care of by |Core|. That case kind of makes sense, but leads to
361 // complications if, e.g., both sides try to do the same thing with their
362 // respective handles simultaneously. The other case, of trying to write the
363 // peer handle to a handle, doesn't make sense -- since no handle will be
364 // available to read the message from.)
365 for (size_t i = 0; i < transports->size(); i++) {
366 if (!(*transports)[i].is_valid())
367 continue;
368 if ((*transports)[i].GetType() == Dispatcher::Type::MESSAGE_PIPE) {
369 MessagePipeDispatcherTransport mp_transport((*transports)[i]);
370 if (mp_transport.GetMessagePipe() == this) {
371 // The other case should have been disallowed by |Core|. (Note: |port|
372 // is the peer port of the handle given to |WriteMessage()|.)
373 DCHECK_EQ(mp_transport.GetPort(), port);
374 return MOJO_RESULT_INVALID_ARGUMENT;
375 }
376 }
377 }
378
379 // Clone the dispatchers and attach them to the message. (This must be done as 362 // Clone the dispatchers and attach them to the message. (This must be done as
380 // a separate loop, since we want to leave the dispatchers alone on failure.) 363 // a separate loop, since we want to leave the dispatchers alone on failure.)
381 std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector()); 364 std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector());
382 dispatchers->reserve(transports->size()); 365 dispatchers->reserve(transports->size());
383 for (size_t i = 0; i < transports->size(); i++) { 366 for (size_t i = 0; i < transports->size(); i++) {
384 if ((*transports)[i].is_valid()) { 367 if ((*transports)[i].is_valid()) {
385 dispatchers->push_back( 368 dispatchers->push_back(
386 (*transports)[i].CreateEquivalentDispatcherAndClose()); 369 (*transports)[i].CreateEquivalentDispatcherAndClose(this, port));
387 } else { 370 } else {
388 LOG(WARNING) << "Enqueueing null dispatcher"; 371 LOG(WARNING) << "Enqueueing null dispatcher";
389 dispatchers->push_back(nullptr); 372 dispatchers->push_back(nullptr);
390 } 373 }
391 } 374 }
392 message->SetDispatchers(std::move(dispatchers)); 375 message->SetDispatchers(std::move(dispatchers));
393 return MOJO_RESULT_OK; 376 return MOJO_RESULT_OK;
394 } 377 }
395 378
396 } // namespace system 379 } // namespace system
397 } // namespace mojo 380 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698