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

Side by Side Diff: mojo/public/cpp/bindings/lib/multiplex_router.cc

Issue 2666423002: Assert sequence validity on non-thread-safe RefCount manipulations (2) (Closed)
Patch Set: rebase Created 3 years, 9 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 | « gpu/command_buffer/service/mailbox_manager_sync.cc ('k') | ppapi/shared_impl/proxy_lock.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/public/cpp/bindings/lib/multiplex_router.h" 5 #include "mojo/public/cpp/bindings/lib/multiplex_router.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 } 424 }
425 425
426 InterfaceId MultiplexRouter::AssociateInterface( 426 InterfaceId MultiplexRouter::AssociateInterface(
427 ScopedInterfaceEndpointHandle handle_to_send) { 427 ScopedInterfaceEndpointHandle handle_to_send) {
428 if (!handle_to_send.pending_association()) 428 if (!handle_to_send.pending_association())
429 return kInvalidInterfaceId; 429 return kInvalidInterfaceId;
430 430
431 uint32_t id = 0; 431 uint32_t id = 0;
432 { 432 {
433 MayAutoLock locker(&lock_); 433 MayAutoLock locker(&lock_);
434 // Relax the cross-thread access restriction to non-thread-safe RefCount.
435 // The lock above protects |endpoint|.
436 base::ScopedAllowCrossThreadRefCountAccess
yzshen1 2017/03/06 17:53:52 Can this opt-out be configured with a type (in thi
437 allow_cross_thread_ref_count_access;
434 do { 438 do {
435 if (next_interface_id_value_ >= kInterfaceIdNamespaceMask) 439 if (next_interface_id_value_ >= kInterfaceIdNamespaceMask)
436 next_interface_id_value_ = 1; 440 next_interface_id_value_ = 1;
437 id = next_interface_id_value_++; 441 id = next_interface_id_value_++;
438 if (set_interface_id_namespace_bit_) 442 if (set_interface_id_namespace_bit_)
439 id |= kInterfaceIdNamespaceMask; 443 id |= kInterfaceIdNamespaceMask;
440 } while (base::ContainsKey(endpoints_, id)); 444 } while (base::ContainsKey(endpoints_, id));
441 445
442 InterfaceEndpoint* endpoint = new InterfaceEndpoint(this, id); 446 InterfaceEndpoint* endpoint = new InterfaceEndpoint(this, id);
443 endpoints_[id] = endpoint; 447 endpoints_[id] = endpoint;
(...skipping 17 matching lines...) Expand all
461 } 465 }
462 return id; 466 return id;
463 } 467 }
464 468
465 ScopedInterfaceEndpointHandle MultiplexRouter::CreateLocalEndpointHandle( 469 ScopedInterfaceEndpointHandle MultiplexRouter::CreateLocalEndpointHandle(
466 InterfaceId id) { 470 InterfaceId id) {
467 if (!IsValidInterfaceId(id)) 471 if (!IsValidInterfaceId(id))
468 return ScopedInterfaceEndpointHandle(); 472 return ScopedInterfaceEndpointHandle();
469 473
470 MayAutoLock locker(&lock_); 474 MayAutoLock locker(&lock_);
475 // Relax the cross-thread access restriction to non-thread-safe RefCount.
476 // The lock above protects |endpoint|.
477 base::ScopedAllowCrossThreadRefCountAccess
478 allow_cross_thread_ref_count_access;
471 bool inserted = false; 479 bool inserted = false;
472 InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, &inserted); 480 InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, &inserted);
473 if (inserted) { 481 if (inserted) {
474 DCHECK(!endpoint->handle_created()); 482 DCHECK(!endpoint->handle_created());
475 483
476 if (encountered_error_) 484 if (encountered_error_)
477 UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED); 485 UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED);
478 } else { 486 } else {
479 // If the endpoint already exist, it is because we have received a 487 // If the endpoint already exist, it is because we have received a
480 // notification that the peer endpoint has closed. 488 // notification that the peer endpoint has closed.
481 CHECK(!endpoint->closed()); 489 CHECK(!endpoint->closed());
482 CHECK(endpoint->peer_closed()); 490 CHECK(endpoint->peer_closed());
483 491
484 if (endpoint->handle_created()) 492 if (endpoint->handle_created())
485 return ScopedInterfaceEndpointHandle(); 493 return ScopedInterfaceEndpointHandle();
486 } 494 }
487 495
488 endpoint->set_handle_created(); 496 endpoint->set_handle_created();
489 return CreateScopedInterfaceEndpointHandle(id); 497 return CreateScopedInterfaceEndpointHandle(id);
490 } 498 }
491 499
492 void MultiplexRouter::CloseEndpointHandle( 500 void MultiplexRouter::CloseEndpointHandle(
493 InterfaceId id, 501 InterfaceId id,
494 const base::Optional<DisconnectReason>& reason) { 502 const base::Optional<DisconnectReason>& reason) {
495 if (!IsValidInterfaceId(id)) 503 if (!IsValidInterfaceId(id))
496 return; 504 return;
497 505
498 MayAutoLock locker(&lock_); 506 MayAutoLock locker(&lock_);
507 // Relax the cross-thread access restriction to non-thread-safe RefCount.
508 // The lock above protects |endpoint|.
509 base::ScopedAllowCrossThreadRefCountAccess
510 allow_cross_thread_ref_count_access;
499 DCHECK(base::ContainsKey(endpoints_, id)); 511 DCHECK(base::ContainsKey(endpoints_, id));
500 InterfaceEndpoint* endpoint = endpoints_[id].get(); 512 InterfaceEndpoint* endpoint = endpoints_[id].get();
501 DCHECK(!endpoint->client()); 513 DCHECK(!endpoint->client());
502 DCHECK(!endpoint->closed()); 514 DCHECK(!endpoint->closed());
503 UpdateEndpointStateMayRemove(endpoint, ENDPOINT_CLOSED); 515 UpdateEndpointStateMayRemove(endpoint, ENDPOINT_CLOSED);
504 516
505 if (!IsMasterInterfaceId(id) || reason) { 517 if (!IsMasterInterfaceId(id) || reason) {
506 MayAutoUnlock unlocker(&lock_); 518 MayAutoUnlock unlocker(&lock_);
507 control_message_proxy_.NotifyPeerEndpointClosed(id, reason); 519 control_message_proxy_.NotifyPeerEndpointClosed(id, reason);
508 } 520 }
509 521
510 ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr); 522 ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr);
511 } 523 }
512 524
513 InterfaceEndpointController* MultiplexRouter::AttachEndpointClient( 525 InterfaceEndpointController* MultiplexRouter::AttachEndpointClient(
514 const ScopedInterfaceEndpointHandle& handle, 526 const ScopedInterfaceEndpointHandle& handle,
515 InterfaceEndpointClient* client, 527 InterfaceEndpointClient* client,
516 scoped_refptr<base::SingleThreadTaskRunner> runner) { 528 scoped_refptr<base::SingleThreadTaskRunner> runner) {
517 const InterfaceId id = handle.id(); 529 const InterfaceId id = handle.id();
518 530
519 DCHECK(IsValidInterfaceId(id)); 531 DCHECK(IsValidInterfaceId(id));
520 DCHECK(client); 532 DCHECK(client);
521 533
522 MayAutoLock locker(&lock_); 534 MayAutoLock locker(&lock_);
535 // Relax the cross-thread access restriction to non-thread-safe RefCount.
536 // The lock above protects |endpoint|.
537 base::ScopedAllowCrossThreadRefCountAccess
538 allow_cross_thread_ref_count_access;
523 DCHECK(base::ContainsKey(endpoints_, id)); 539 DCHECK(base::ContainsKey(endpoints_, id));
524 540
525 InterfaceEndpoint* endpoint = endpoints_[id].get(); 541 InterfaceEndpoint* endpoint = endpoints_[id].get();
526 endpoint->AttachClient(client, std::move(runner)); 542 endpoint->AttachClient(client, std::move(runner));
527 543
528 if (endpoint->peer_closed()) 544 if (endpoint->peer_closed())
529 tasks_.push_back(Task::CreateNotifyErrorTask(endpoint)); 545 tasks_.push_back(Task::CreateNotifyErrorTask(endpoint));
530 ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr); 546 ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr);
531 547
532 return endpoint; 548 return endpoint;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 // No need to trigger a ProcessTasks() because it is already on the stack. 701 // No need to trigger a ProcessTasks() because it is already on the stack.
686 702
687 return true; 703 return true;
688 } 704 }
689 705
690 void MultiplexRouter::OnPipeConnectionError() { 706 void MultiplexRouter::OnPipeConnectionError() {
691 DCHECK(thread_checker_.CalledOnValidThread()); 707 DCHECK(thread_checker_.CalledOnValidThread());
692 708
693 scoped_refptr<MultiplexRouter> protector(this); 709 scoped_refptr<MultiplexRouter> protector(this);
694 MayAutoLock locker(&lock_); 710 MayAutoLock locker(&lock_);
711 // Relax the cross-thread access restriction to non-thread-safe RefCount.
712 // The lock above protects |endpoint|.
713 base::ScopedAllowCrossThreadRefCountAccess
714 allow_cross_thread_ref_count_access;
695 715
696 encountered_error_ = true; 716 encountered_error_ = true;
697 717
698 for (auto iter = endpoints_.begin(); iter != endpoints_.end();) { 718 for (auto iter = endpoints_.begin(); iter != endpoints_.end();) {
699 InterfaceEndpoint* endpoint = iter->second.get(); 719 InterfaceEndpoint* endpoint = iter->second.get();
700 // Increment the iterator before calling UpdateEndpointStateMayRemove() 720 // Increment the iterator before calling UpdateEndpointStateMayRemove()
701 // because it may remove the corresponding value from the map. 721 // because it may remove the corresponding value from the map.
702 ++iter; 722 ++iter;
703 723
704 if (endpoint->client()) 724 if (endpoint->client())
705 tasks_.push_back(Task::CreateNotifyErrorTask(endpoint)); 725 tasks_.push_back(Task::CreateNotifyErrorTask(endpoint));
706 726
707 UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED); 727 UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED);
708 } 728 }
709 729
710 ProcessTasks(connector_.during_sync_handle_watcher_callback() 730 ProcessTasks(connector_.during_sync_handle_watcher_callback()
711 ? ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES 731 ? ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES
712 : ALLOW_DIRECT_CLIENT_CALLS, 732 : ALLOW_DIRECT_CLIENT_CALLS,
713 connector_.task_runner()); 733 connector_.task_runner());
714 } 734 }
715 735
716 void MultiplexRouter::ProcessTasks( 736 void MultiplexRouter::ProcessTasks(
717 ClientCallBehavior client_call_behavior, 737 ClientCallBehavior client_call_behavior,
718 base::SingleThreadTaskRunner* current_task_runner) { 738 base::SingleThreadTaskRunner* current_task_runner) {
719 AssertLockAcquired(); 739 AssertLockAcquired();
740 // Relax the cross-thread access restriction to non-thread-safe RefCount.
741 // The lock above protects |endpoint|.
742 base::ScopedAllowCrossThreadRefCountAccess
743 allow_cross_thread_ref_count_access;
720 744
721 if (posted_to_process_tasks_) 745 if (posted_to_process_tasks_)
722 return; 746 return;
723 747
724 while (!tasks_.empty() && !paused_) { 748 while (!tasks_.empty() && !paused_) {
725 std::unique_ptr<Task> task(std::move(tasks_.front())); 749 std::unique_ptr<Task> task(std::move(tasks_.front()));
726 tasks_.pop_front(); 750 tasks_.pop_front();
727 751
728 InterfaceId id = kInvalidInterfaceId; 752 InterfaceId id = kInvalidInterfaceId;
729 bool sync_message = 753 bool sync_message =
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 1001
978 void MultiplexRouter::AssertLockAcquired() { 1002 void MultiplexRouter::AssertLockAcquired() {
979 #if DCHECK_IS_ON() 1003 #if DCHECK_IS_ON()
980 if (lock_) 1004 if (lock_)
981 lock_->AssertAcquired(); 1005 lock_->AssertAcquired();
982 #endif 1006 #endif
983 } 1007 }
984 1008
985 } // namespace internal 1009 } // namespace internal
986 } // namespace mojo 1010 } // namespace mojo
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/mailbox_manager_sync.cc ('k') | ppapi/shared_impl/proxy_lock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698