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

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

Issue 612903003: Mojo: Split up Channel::RemoveMessagePipeEndpoint(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@del_onremove
Patch Set: rebased Created 6 years, 2 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
« no previous file with comments | « mojo/system/channel.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/channel.h" 5 #include "mojo/system/channel.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 if (!RunMessagePipeEndpoint(message_view.destination_id(), 410 if (!RunMessagePipeEndpoint(message_view.destination_id(),
411 message_view.source_id())) { 411 message_view.source_id())) {
412 HandleRemoteError( 412 HandleRemoteError(
413 "Received invalid channel message to run message pipe"); 413 "Received invalid channel message to run message pipe");
414 } 414 }
415 break; 415 break;
416 case MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint: 416 case MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint:
417 DVLOG(2) << "Handling channel message to remove message pipe (local ID " 417 DVLOG(2) << "Handling channel message to remove message pipe (local ID "
418 << message_view.destination_id() << ", remote ID " 418 << message_view.destination_id() << ", remote ID "
419 << message_view.source_id() << ")"; 419 << message_view.source_id() << ")";
420 if (!RemoveMessagePipeEndpoint(message_view.destination_id(), 420 if (!OnRemoveMessagePipeEndpoint(message_view.destination_id(),
421 message_view.source_id())) { 421 message_view.source_id())) {
422 HandleRemoteError( 422 HandleRemoteError(
423 "Received invalid channel message to remove message pipe"); 423 "Received invalid channel message to remove message pipe");
424 } 424 }
425 break; 425 break;
426 case MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck: 426 case MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck:
427 DVLOG(2) << "Handling channel message to ack remove message pipe (local " 427 DVLOG(2) << "Handling channel message to ack remove message pipe (local "
428 "ID " << message_view.destination_id() << ", remote ID " 428 "ID " << message_view.destination_id() << ", remote ID "
429 << message_view.source_id() << ")"; 429 << message_view.source_id() << ")";
430 if (!RemoveMessagePipeEndpoint(message_view.destination_id(), 430 if (!OnRemoveMessagePipeEndpointAck(message_view.destination_id())) {
431 message_view.source_id())) {
432 HandleRemoteError( 431 HandleRemoteError(
433 "Received invalid channel message to ack remove message pipe"); 432 "Received invalid channel message to ack remove message pipe");
434 } 433 }
435 break; 434 break;
436 default: 435 default:
437 HandleRemoteError("Received invalid channel message"); 436 HandleRemoteError("Received invalid channel message");
438 NOTREACHED(); 437 NOTREACHED();
439 break; 438 break;
440 } 439 }
441 } 440 }
442 441
443 bool Channel::RemoveMessagePipeEndpoint( 442 bool Channel::OnRemoveMessagePipeEndpoint(
444 MessageInTransit::EndpointId local_id, 443 MessageInTransit::EndpointId local_id,
445 MessageInTransit::EndpointId remote_id) { 444 MessageInTransit::EndpointId remote_id) {
446 DCHECK(creation_thread_checker_.CalledOnValidThread()); 445 DCHECK(creation_thread_checker_.CalledOnValidThread());
447 446
448 // If this is non-null after the locked block, the endpoint should be detached
449 // (and no remove ack message sent).
450 scoped_refptr<ChannelEndpoint> endpoint_to_detach;
451 scoped_refptr<MessagePipe> message_pipe; 447 scoped_refptr<MessagePipe> message_pipe;
452 unsigned port = ~0u; 448 unsigned port = ~0u;
453 { 449 {
454 base::AutoLock locker(lock_); 450 base::AutoLock locker(lock_);
455 451
456 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); 452 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id);
457 if (it == local_id_to_endpoint_map_.end()) { 453 if (it == local_id_to_endpoint_map_.end()) {
458 DVLOG(2) << "Remove message pipe error: not found"; 454 DVLOG(2) << "Remove message pipe endpoint error: not found";
459 return false; 455 return false;
460 } 456 }
461 457
462 switch (it->second->state_) { 458 switch (it->second->state_) {
463 case ChannelEndpoint::STATE_NORMAL: 459 case ChannelEndpoint::STATE_NORMAL:
464 it->second->state_ = ChannelEndpoint::STATE_WAIT_LOCAL_DETACH; 460 // This is the normal case; we'll proceed on to "wait local detach".
465 message_pipe = it->second->message_pipe_;
466 port = it->second->port_;
467 it->second->message_pipe_ = nullptr;
468 // We have to send a remove ack message (outside the lock).
469 break; 461 break;
462
470 case ChannelEndpoint::STATE_WAIT_LOCAL_DETACH: 463 case ChannelEndpoint::STATE_WAIT_LOCAL_DETACH:
471 DVLOG(2) << "Remove message pipe error: wrong state"; 464 // We can only be in this state because we got a "remove" already, so
465 // getting another such message is invalid.
466 DVLOG(2) << "Remove message pipe endpoint error: wrong state";
472 return false; 467 return false;
468
473 case ChannelEndpoint::STATE_WAIT_REMOTE_REMOVE_ACK: 469 case ChannelEndpoint::STATE_WAIT_REMOTE_REMOVE_ACK:
474 endpoint_to_detach = it->second; 470 // Remove messages "crossed"; we have to wait for the ack.
475 local_id_to_endpoint_map_.erase(it); 471 return true;
476 // We have to detach (outside the lock).
477 break;
478 } 472 }
479 } 473
480 if (endpoint_to_detach.get()) { 474 it->second->state_ = ChannelEndpoint::STATE_WAIT_LOCAL_DETACH;
481 endpoint_to_detach->DetachFromChannel(); 475 message_pipe = it->second->message_pipe_;
482 return true; 476 port = it->second->port_;
477 it->second->message_pipe_ = nullptr;
478 // Send the remove ack message outside the lock.
483 } 479 }
484 480
485 if (!SendControlMessage( 481 if (!SendControlMessage(
486 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck, 482 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck,
487 local_id, 483 local_id,
488 remote_id)) { 484 remote_id)) {
489 HandleLocalError(base::StringPrintf( 485 HandleLocalError(base::StringPrintf(
490 "Failed to send message to remove remote message pipe endpoint ack " 486 "Failed to send message to remove remote message pipe endpoint ack "
491 "(local ID %u, remote ID %u)", 487 "(local ID %u, remote ID %u)",
492 static_cast<unsigned>(local_id), 488 static_cast<unsigned>(local_id),
493 static_cast<unsigned>(remote_id))); 489 static_cast<unsigned>(remote_id)));
494 } 490 }
495 491
496 message_pipe->Close(port); 492 message_pipe->Close(port);
497
498 return true; 493 return true;
499 } 494 }
500 495
496 bool Channel::OnRemoveMessagePipeEndpointAck(
497 MessageInTransit::EndpointId local_id) {
498 DCHECK(creation_thread_checker_.CalledOnValidThread());
499
500 scoped_refptr<ChannelEndpoint> endpoint_to_detach;
501 {
502 base::AutoLock locker(lock_);
503
504 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id);
505 if (it == local_id_to_endpoint_map_.end()) {
506 DVLOG(2) << "Remove message pipe endpoint ack error: not found";
507 return false;
508 }
509
510 if (it->second->state_ != ChannelEndpoint::STATE_WAIT_REMOTE_REMOVE_ACK) {
511 DVLOG(2) << "Remove message pipe endpoint ack error: wrong state";
512 return false;
513 }
514
515 endpoint_to_detach = it->second;
516 local_id_to_endpoint_map_.erase(it);
517 // Detach the endpoint outside the lock.
518 }
519
520 endpoint_to_detach->DetachFromChannel();
521 return true;
522 }
523
501 bool Channel::SendControlMessage(MessageInTransit::Subtype subtype, 524 bool Channel::SendControlMessage(MessageInTransit::Subtype subtype,
502 MessageInTransit::EndpointId local_id, 525 MessageInTransit::EndpointId local_id,
503 MessageInTransit::EndpointId remote_id) { 526 MessageInTransit::EndpointId remote_id) {
504 DVLOG(2) << "Sending channel control message: subtype " << subtype 527 DVLOG(2) << "Sending channel control message: subtype " << subtype
505 << ", local ID " << local_id << ", remote ID " << remote_id; 528 << ", local ID " << local_id << ", remote ID " << remote_id;
506 scoped_ptr<MessageInTransit> message(new MessageInTransit( 529 scoped_ptr<MessageInTransit> message(new MessageInTransit(
507 MessageInTransit::kTypeChannel, subtype, 0, nullptr)); 530 MessageInTransit::kTypeChannel, subtype, 0, nullptr));
508 message->set_source_id(local_id); 531 message->set_source_id(local_id);
509 message->set_destination_id(remote_id); 532 message->set_destination_id(remote_id);
510 return WriteMessage(message.Pass()); 533 return WriteMessage(message.Pass());
511 } 534 }
512 535
513 void Channel::HandleRemoteError(const base::StringPiece& error_message) { 536 void Channel::HandleRemoteError(const base::StringPiece& error_message) {
514 // TODO(vtl): Is this how we really want to handle this? Probably we want to 537 // TODO(vtl): Is this how we really want to handle this? Probably we want to
515 // terminate the connection, since it's spewing invalid stuff. 538 // terminate the connection, since it's spewing invalid stuff.
516 LOG(WARNING) << error_message; 539 LOG(WARNING) << error_message;
517 } 540 }
518 541
519 void Channel::HandleLocalError(const base::StringPiece& error_message) { 542 void Channel::HandleLocalError(const base::StringPiece& error_message) {
520 // TODO(vtl): Is this how we really want to handle this? 543 // TODO(vtl): Is this how we really want to handle this?
521 // Sometimes we'll want to propagate the error back to the message pipe 544 // Sometimes we'll want to propagate the error back to the message pipe
522 // (endpoint), and notify it that the remote is (effectively) closed. 545 // (endpoint), and notify it that the remote is (effectively) closed.
523 // Sometimes we'll want to kill the channel (and notify all the endpoints that 546 // Sometimes we'll want to kill the channel (and notify all the endpoints that
524 // their remotes are dead. 547 // their remotes are dead.
525 LOG(WARNING) << error_message; 548 LOG(WARNING) << error_message;
526 } 549 }
527 550
528 } // namespace system 551 } // namespace system
529 } // namespace mojo 552 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/channel.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698