Commit 053dc146 authored by yzshen's avatar yzshen Committed by Commit bot

Mojo C++ bindings: remove the lock in MultiplexRouter if it only serves a single interface.

BUG=594244

Review-Url: https://codereview.chromium.org/2345013002
Cr-Commit-Position: refs/heads/master@{#419036}
parent 90625243
...@@ -55,6 +55,7 @@ static_library("bindings") { ...@@ -55,6 +55,7 @@ static_library("bindings") {
"lib/interface_ptr_state.h", "lib/interface_ptr_state.h",
"lib/map_data_internal.h", "lib/map_data_internal.h",
"lib/map_serialization.h", "lib/map_serialization.h",
"lib/may_auto_lock.h",
"lib/message.cc", "lib/message.cc",
"lib/message_buffer.cc", "lib/message_buffer.cc",
"lib/message_buffer.h", "lib/message_buffer.h",
......
...@@ -231,8 +231,9 @@ template <typename Interface> ...@@ -231,8 +231,9 @@ template <typename Interface>
void GetDummyProxyForTesting(AssociatedInterfacePtr<Interface>* proxy) { void GetDummyProxyForTesting(AssociatedInterfacePtr<Interface>* proxy) {
MessagePipe pipe; MessagePipe pipe;
scoped_refptr<internal::MultiplexRouter> router = scoped_refptr<internal::MultiplexRouter> router =
new internal::MultiplexRouter(false, std::move(pipe.handle0), new internal::MultiplexRouter(std::move(pipe.handle0),
base::ThreadTaskRunnerHandle::Get()); internal::MultiplexRouter::MULTI_INTERFACE,
false, base::ThreadTaskRunnerHandle::Get());
std::unique_ptr<AssociatedGroup> group = router->CreateAssociatedGroup(); std::unique_ptr<AssociatedGroup> group = router->CreateAssociatedGroup();
GetProxy(proxy, group.get()); GetProxy(proxy, group.get());
} }
......
...@@ -146,7 +146,8 @@ void MultiplexedBindingState::BindInternal( ...@@ -146,7 +146,8 @@ void MultiplexedBindingState::BindInternal(
uint32_t interface_version) { uint32_t interface_version) {
DCHECK(!router_); DCHECK(!router_);
router_ = new internal::MultiplexRouter(false, std::move(handle), runner); router_ = new MultiplexRouter(
std::move(handle), MultiplexRouter::MULTI_INTERFACE, false, runner);
router_->SetMasterInterfaceName(interface_name); router_->SetMasterInterfaceName(interface_name);
endpoint_client_.reset(new InterfaceEndpointClient( endpoint_client_.reset(new InterfaceEndpointClient(
......
...@@ -12,37 +12,11 @@ ...@@ -12,37 +12,11 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
#include "mojo/public/cpp/bindings/sync_handle_watcher.h" #include "mojo/public/cpp/bindings/sync_handle_watcher.h"
namespace mojo { namespace mojo {
namespace {
// Similar to base::AutoLock, except that it does nothing if |lock| passed into
// the constructor is null.
class MayAutoLock {
public:
explicit MayAutoLock(base::Lock* lock) : lock_(lock) {
if (lock_)
lock_->Acquire();
}
~MayAutoLock() {
if (lock_) {
lock_->AssertAcquired();
lock_->Release();
}
}
private:
base::Lock* lock_;
DISALLOW_COPY_AND_ASSIGN(MayAutoLock);
};
} // namespace
// ----------------------------------------------------------------------------
Connector::Connector(ScopedMessagePipeHandle message_pipe, Connector::Connector(ScopedMessagePipeHandle message_pipe,
ConnectorConfig config, ConnectorConfig config,
scoped_refptr<base::SingleThreadTaskRunner> runner) scoped_refptr<base::SingleThreadTaskRunner> runner)
...@@ -73,7 +47,7 @@ void Connector::CloseMessagePipe() { ...@@ -73,7 +47,7 @@ void Connector::CloseMessagePipe() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
CancelWait(); CancelWait();
MayAutoLock locker(lock_.get()); internal::MayAutoLock locker(lock_.get());
message_pipe_.reset(); message_pipe_.reset();
base::AutoLock lock(connected_lock_); base::AutoLock lock(connected_lock_);
...@@ -84,7 +58,7 @@ ScopedMessagePipeHandle Connector::PassMessagePipe() { ...@@ -84,7 +58,7 @@ ScopedMessagePipeHandle Connector::PassMessagePipe() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
CancelWait(); CancelWait();
MayAutoLock locker(lock_.get()); internal::MayAutoLock locker(lock_.get());
ScopedMessagePipeHandle message_pipe = std::move(message_pipe_); ScopedMessagePipeHandle message_pipe = std::move(message_pipe_);
base::AutoLock lock(connected_lock_); base::AutoLock lock(connected_lock_);
...@@ -149,7 +123,7 @@ bool Connector::Accept(Message* message) { ...@@ -149,7 +123,7 @@ bool Connector::Accept(Message* message) {
if (error_) if (error_)
return false; return false;
MayAutoLock locker(lock_.get()); internal::MayAutoLock locker(lock_.get());
if (!message_pipe_.is_valid() || drop_writes_) if (!message_pipe_.is_valid() || drop_writes_)
return true; return true;
...@@ -331,7 +305,7 @@ void Connector::HandleError(bool force_pipe_reset, bool force_async_handler) { ...@@ -331,7 +305,7 @@ void Connector::HandleError(bool force_pipe_reset, bool force_async_handler) {
if (force_pipe_reset) { if (force_pipe_reset) {
CancelWait(); CancelWait();
MayAutoLock locker(lock_.get()); internal::MayAutoLock locker(lock_.get());
message_pipe_.reset(); message_pipe_.reset();
MessagePipe dummy_pipe; MessagePipe dummy_pipe;
message_pipe_ = std::move(dummy_pipe.handle0); message_pipe_ = std::move(dummy_pipe.handle0);
......
...@@ -345,7 +345,8 @@ class InterfacePtrState<Interface, true> { ...@@ -345,7 +345,8 @@ class InterfacePtrState<Interface, true> {
if (!handle_.is_valid()) if (!handle_.is_valid())
return; return;
router_ = new MultiplexRouter(true, std::move(handle_), runner_); router_ = new MultiplexRouter(
std::move(handle_), MultiplexRouter::MULTI_INTERFACE, true, runner_);
router_->SetMasterInterfaceName(Interface::Name_); router_->SetMasterInterfaceName(Interface::Name_);
endpoint_client_.reset(new InterfaceEndpointClient( endpoint_client_.reset(new InterfaceEndpointClient(
router_->CreateLocalEndpointHandle(kMasterInterfaceId), nullptr, router_->CreateLocalEndpointHandle(kMasterInterfaceId), nullptr,
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/macros.h"
#include "base/synchronization/lock.h"
namespace mojo {
namespace internal {
// Similar to base::AutoLock, except that it does nothing if |lock| passed into
// the constructor is null.
class MayAutoLock {
public:
explicit MayAutoLock(base::Lock* lock) : lock_(lock) {
if (lock_)
lock_->Acquire();
}
~MayAutoLock() {
if (lock_) {
lock_->AssertAcquired();
lock_->Release();
}
}
private:
base::Lock* lock_;
DISALLOW_COPY_AND_ASSIGN(MayAutoLock);
};
// Similar to base::AutoUnlock, except that it does nothing if |lock| passed
// into the constructor is null.
class MayAutoUnlock {
public:
explicit MayAutoUnlock(base::Lock* lock) : lock_(lock) {
if (lock_) {
lock_->AssertAcquired();
lock_->Release();
}
}
~MayAutoUnlock() {
if (lock_)
lock_->Acquire();
}
private:
base::Lock* lock_;
DISALLOW_COPY_AND_ASSIGN(MayAutoUnlock);
};
} // namespace internal
} // namespace mojo
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "mojo/public/cpp/bindings/associated_group.h" #include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/interface_endpoint_client.h" #include "mojo/public/cpp/bindings/interface_endpoint_client.h"
#include "mojo/public/cpp/bindings/interface_endpoint_controller.h" #include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
#include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
#include "mojo/public/cpp/bindings/sync_handle_watcher.h" #include "mojo/public/cpp/bindings/sync_handle_watcher.h"
namespace mojo { namespace mojo {
...@@ -50,13 +51,13 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -50,13 +51,13 @@ class MultiplexRouter::InterfaceEndpoint
bool closed() const { return closed_; } bool closed() const { return closed_; }
void set_closed() { void set_closed() {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
closed_ = true; closed_ = true;
} }
bool peer_closed() const { return peer_closed_; } bool peer_closed() const { return peer_closed_; }
void set_peer_closed() { void set_peer_closed() {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
peer_closed_ = true; peer_closed_ = true;
} }
...@@ -68,7 +69,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -68,7 +69,7 @@ class MultiplexRouter::InterfaceEndpoint
void AttachClient(InterfaceEndpointClient* client, void AttachClient(InterfaceEndpointClient* client,
scoped_refptr<base::SingleThreadTaskRunner> runner) { scoped_refptr<base::SingleThreadTaskRunner> runner) {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
DCHECK(!client_); DCHECK(!client_);
DCHECK(!closed_); DCHECK(!closed_);
DCHECK(runner->BelongsToCurrentThread()); DCHECK(runner->BelongsToCurrentThread());
...@@ -80,7 +81,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -80,7 +81,7 @@ class MultiplexRouter::InterfaceEndpoint
// This method must be called on the same thread as the corresponding // This method must be called on the same thread as the corresponding
// AttachClient() call. // AttachClient() call.
void DetachClient() { void DetachClient() {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
DCHECK(client_); DCHECK(client_);
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(!closed_); DCHECK(!closed_);
...@@ -91,7 +92,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -91,7 +92,7 @@ class MultiplexRouter::InterfaceEndpoint
} }
void SignalSyncMessageEvent() { void SignalSyncMessageEvent() {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
if (event_signalled_) if (event_signalled_)
return; return;
...@@ -104,7 +105,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -104,7 +105,7 @@ class MultiplexRouter::InterfaceEndpoint
} }
void ResetSyncMessageSignal() { void ResetSyncMessageSignal() {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
if (!event_signalled_) if (!event_signalled_)
return; return;
...@@ -146,7 +147,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -146,7 +147,7 @@ class MultiplexRouter::InterfaceEndpoint
friend class base::RefCounted<InterfaceEndpoint>; friend class base::RefCounted<InterfaceEndpoint>;
~InterfaceEndpoint() override { ~InterfaceEndpoint() override {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
DCHECK(!client_); DCHECK(!client_);
DCHECK(closed_); DCHECK(closed_);
...@@ -164,7 +165,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -164,7 +165,7 @@ class MultiplexRouter::InterfaceEndpoint
DCHECK_EQ(MOJO_RESULT_OK, result); DCHECK_EQ(MOJO_RESULT_OK, result);
bool reset_sync_watcher = false; bool reset_sync_watcher = false;
{ {
base::AutoLock locker(router_->lock_); MayAutoLock locker(router_->lock_.get());
bool more_to_process = router_->ProcessFirstSyncMessageForEndpoint(id_); bool more_to_process = router_->ProcessFirstSyncMessageForEndpoint(id_);
...@@ -189,7 +190,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -189,7 +190,7 @@ class MultiplexRouter::InterfaceEndpoint
return; return;
{ {
base::AutoLock locker(router_->lock_); MayAutoLock locker(router_->lock_.get());
EnsureEventMessagePipeExists(); EnsureEventMessagePipeExists();
auto iter = router_->sync_message_tasks_.find(id_); auto iter = router_->sync_message_tasks_.find(id_);
...@@ -203,7 +204,7 @@ class MultiplexRouter::InterfaceEndpoint ...@@ -203,7 +204,7 @@ class MultiplexRouter::InterfaceEndpoint
} }
void EnsureEventMessagePipeExists() { void EnsureEventMessagePipeExists() {
router_->lock_.AssertAcquired(); router_->AssertLockAcquired();
if (sync_message_event_receiver_.is_valid()) if (sync_message_event_receiver_.is_valid())
return; return;
...@@ -281,16 +282,19 @@ struct MultiplexRouter::Task { ...@@ -281,16 +282,19 @@ struct MultiplexRouter::Task {
}; };
MultiplexRouter::MultiplexRouter( MultiplexRouter::MultiplexRouter(
bool set_interface_id_namesapce_bit,
ScopedMessagePipeHandle message_pipe, ScopedMessagePipeHandle message_pipe,
Config config,
bool set_interface_id_namesapce_bit,
scoped_refptr<base::SingleThreadTaskRunner> runner) scoped_refptr<base::SingleThreadTaskRunner> runner)
: set_interface_id_namespace_bit_(set_interface_id_namesapce_bit), : set_interface_id_namespace_bit_(set_interface_id_namesapce_bit),
task_runner_(runner), task_runner_(runner),
header_validator_(nullptr), header_validator_(nullptr),
filters_(this), filters_(this),
connector_(std::move(message_pipe), connector_(std::move(message_pipe),
Connector::MULTI_THREADED_SEND, config == SINGLE_INTERFACE ? Connector::SINGLE_THREADED_SEND
: Connector::MULTI_THREADED_SEND,
std::move(runner)), std::move(runner)),
lock_(config == SINGLE_INTERFACE ? nullptr : new base::Lock),
control_message_handler_(this), control_message_handler_(this),
control_message_proxy_(&connector_), control_message_proxy_(&connector_),
next_interface_id_value_(1), next_interface_id_value_(1),
...@@ -315,7 +319,7 @@ MultiplexRouter::MultiplexRouter( ...@@ -315,7 +319,7 @@ MultiplexRouter::MultiplexRouter(
} }
MultiplexRouter::~MultiplexRouter() { MultiplexRouter::~MultiplexRouter() {
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
sync_message_tasks_.clear(); sync_message_tasks_.clear();
tasks_.clear(); tasks_.clear();
...@@ -343,7 +347,7 @@ void MultiplexRouter::SetMasterInterfaceName(const std::string& name) { ...@@ -343,7 +347,7 @@ void MultiplexRouter::SetMasterInterfaceName(const std::string& name) {
void MultiplexRouter::CreateEndpointHandlePair( void MultiplexRouter::CreateEndpointHandlePair(
ScopedInterfaceEndpointHandle* local_endpoint, ScopedInterfaceEndpointHandle* local_endpoint,
ScopedInterfaceEndpointHandle* remote_endpoint) { ScopedInterfaceEndpointHandle* remote_endpoint) {
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
uint32_t id = 0; uint32_t id = 0;
do { do {
if (next_interface_id_value_ >= kInterfaceIdNamespaceMask) if (next_interface_id_value_ >= kInterfaceIdNamespaceMask)
...@@ -367,7 +371,7 @@ ScopedInterfaceEndpointHandle MultiplexRouter::CreateLocalEndpointHandle( ...@@ -367,7 +371,7 @@ ScopedInterfaceEndpointHandle MultiplexRouter::CreateLocalEndpointHandle(
if (!IsValidInterfaceId(id)) if (!IsValidInterfaceId(id))
return ScopedInterfaceEndpointHandle(); return ScopedInterfaceEndpointHandle();
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
bool inserted = false; bool inserted = false;
InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, &inserted); InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, &inserted);
if (inserted) { if (inserted) {
...@@ -386,7 +390,7 @@ void MultiplexRouter::CloseEndpointHandle(InterfaceId id, bool is_local) { ...@@ -386,7 +390,7 @@ void MultiplexRouter::CloseEndpointHandle(InterfaceId id, bool is_local) {
if (!IsValidInterfaceId(id)) if (!IsValidInterfaceId(id))
return; return;
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
if (!is_local) { if (!is_local) {
DCHECK(base::ContainsKey(endpoints_, id)); DCHECK(base::ContainsKey(endpoints_, id));
...@@ -419,7 +423,7 @@ InterfaceEndpointController* MultiplexRouter::AttachEndpointClient( ...@@ -419,7 +423,7 @@ InterfaceEndpointController* MultiplexRouter::AttachEndpointClient(
DCHECK(IsValidInterfaceId(id)); DCHECK(IsValidInterfaceId(id));
DCHECK(client); DCHECK(client);
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
DCHECK(base::ContainsKey(endpoints_, id)); DCHECK(base::ContainsKey(endpoints_, id));
InterfaceEndpoint* endpoint = endpoints_[id].get(); InterfaceEndpoint* endpoint = endpoints_[id].get();
...@@ -438,7 +442,7 @@ void MultiplexRouter::DetachEndpointClient( ...@@ -438,7 +442,7 @@ void MultiplexRouter::DetachEndpointClient(
DCHECK(IsValidInterfaceId(id)); DCHECK(IsValidInterfaceId(id));
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
DCHECK(base::ContainsKey(endpoints_, id)); DCHECK(base::ContainsKey(endpoints_, id));
InterfaceEndpoint* endpoint = endpoints_[id].get(); InterfaceEndpoint* endpoint = endpoints_[id].get();
...@@ -467,7 +471,7 @@ void MultiplexRouter::PauseIncomingMethodCallProcessing() { ...@@ -467,7 +471,7 @@ void MultiplexRouter::PauseIncomingMethodCallProcessing() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
connector_.PauseIncomingMethodCallProcessing(); connector_.PauseIncomingMethodCallProcessing();
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
paused_ = true; paused_ = true;
for (auto iter = endpoints_.begin(); iter != endpoints_.end(); ++iter) for (auto iter = endpoints_.begin(); iter != endpoints_.end(); ++iter)
...@@ -478,7 +482,7 @@ void MultiplexRouter::ResumeIncomingMethodCallProcessing() { ...@@ -478,7 +482,7 @@ void MultiplexRouter::ResumeIncomingMethodCallProcessing() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
connector_.ResumeIncomingMethodCallProcessing(); connector_.ResumeIncomingMethodCallProcessing();
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
paused_ = false; paused_ = false;
for (auto iter = endpoints_.begin(); iter != endpoints_.end(); ++iter) { for (auto iter = endpoints_.begin(); iter != endpoints_.end(); ++iter) {
...@@ -492,7 +496,7 @@ void MultiplexRouter::ResumeIncomingMethodCallProcessing() { ...@@ -492,7 +496,7 @@ void MultiplexRouter::ResumeIncomingMethodCallProcessing() {
bool MultiplexRouter::HasAssociatedEndpoints() const { bool MultiplexRouter::HasAssociatedEndpoints() const {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
if (endpoints_.size() > 1) if (endpoints_.size() > 1)
return true; return true;
...@@ -504,7 +508,7 @@ bool MultiplexRouter::HasAssociatedEndpoints() const { ...@@ -504,7 +508,7 @@ bool MultiplexRouter::HasAssociatedEndpoints() const {
void MultiplexRouter::EnableTestingMode() { void MultiplexRouter::EnableTestingMode() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
testing_mode_ = true; testing_mode_ = true;
connector_.set_enforce_errors_from_incoming_receiver(false); connector_.set_enforce_errors_from_incoming_receiver(false);
...@@ -514,7 +518,7 @@ bool MultiplexRouter::Accept(Message* message) { ...@@ -514,7 +518,7 @@ bool MultiplexRouter::Accept(Message* message) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
scoped_refptr<MultiplexRouter> protector(this); scoped_refptr<MultiplexRouter> protector(this);
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
DCHECK(!paused_); DCHECK(!paused_);
...@@ -553,7 +557,7 @@ bool MultiplexRouter::Accept(Message* message) { ...@@ -553,7 +557,7 @@ bool MultiplexRouter::Accept(Message* message) {
} }
bool MultiplexRouter::OnPeerAssociatedEndpointClosed(InterfaceId id) { bool MultiplexRouter::OnPeerAssociatedEndpointClosed(InterfaceId id) {
lock_.AssertAcquired(); AssertLockAcquired();
if (IsMasterInterfaceId(id)) if (IsMasterInterfaceId(id))
return false; return false;
...@@ -578,7 +582,7 @@ bool MultiplexRouter::OnPeerAssociatedEndpointClosed(InterfaceId id) { ...@@ -578,7 +582,7 @@ bool MultiplexRouter::OnPeerAssociatedEndpointClosed(InterfaceId id) {
} }
bool MultiplexRouter::OnAssociatedEndpointClosedBeforeSent(InterfaceId id) { bool MultiplexRouter::OnAssociatedEndpointClosedBeforeSent(InterfaceId id) {
lock_.AssertAcquired(); AssertLockAcquired();
if (IsMasterInterfaceId(id)) if (IsMasterInterfaceId(id))
return false; return false;
...@@ -596,7 +600,7 @@ void MultiplexRouter::OnPipeConnectionError() { ...@@ -596,7 +600,7 @@ void MultiplexRouter::OnPipeConnectionError() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
scoped_refptr<MultiplexRouter> protector(this); scoped_refptr<MultiplexRouter> protector(this);
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
encountered_error_ = true; encountered_error_ = true;
...@@ -621,7 +625,7 @@ void MultiplexRouter::OnPipeConnectionError() { ...@@ -621,7 +625,7 @@ void MultiplexRouter::OnPipeConnectionError() {
void MultiplexRouter::ProcessTasks( void MultiplexRouter::ProcessTasks(
ClientCallBehavior client_call_behavior, ClientCallBehavior client_call_behavior,
base::SingleThreadTaskRunner* current_task_runner) { base::SingleThreadTaskRunner* current_task_runner) {
lock_.AssertAcquired(); AssertLockAcquired();
if (posted_to_process_tasks_) if (posted_to_process_tasks_)
return; return;
...@@ -665,7 +669,7 @@ void MultiplexRouter::ProcessTasks( ...@@ -665,7 +669,7 @@ void MultiplexRouter::ProcessTasks(
} }
bool MultiplexRouter::ProcessFirstSyncMessageForEndpoint(InterfaceId id) { bool MultiplexRouter::ProcessFirstSyncMessageForEndpoint(InterfaceId id) {
lock_.AssertAcquired(); AssertLockAcquired();
auto iter = sync_message_tasks_.find(id); auto iter = sync_message_tasks_.find(id);
if (iter == sync_message_tasks_.end()) if (iter == sync_message_tasks_.end())
...@@ -704,7 +708,7 @@ bool MultiplexRouter::ProcessNotifyErrorTask( ...@@ -704,7 +708,7 @@ bool MultiplexRouter::ProcessNotifyErrorTask(
DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread()); DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread());
DCHECK(!paused_); DCHECK(!paused_);
lock_.AssertAcquired(); AssertLockAcquired();
InterfaceEndpoint* endpoint = task->endpoint_to_notify.get(); InterfaceEndpoint* endpoint = task->endpoint_to_notify.get();
if (!endpoint->client()) if (!endpoint->client())
return true; return true;
...@@ -724,7 +728,7 @@ bool MultiplexRouter::ProcessNotifyErrorTask( ...@@ -724,7 +728,7 @@ bool MultiplexRouter::ProcessNotifyErrorTask(
// //
// It is safe to call into |client| without the lock. Because |client| is // It is safe to call into |client| without the lock. Because |client| is
// always accessed on the same thread, including DetachEndpointClient(). // always accessed on the same thread, including DetachEndpointClient().
base::AutoUnlock unlocker(lock_); MayAutoUnlock unlocker(lock_.get());
client->NotifyError(); client->NotifyError();
} }
return true; return true;
...@@ -737,7 +741,7 @@ bool MultiplexRouter::ProcessIncomingMessage( ...@@ -737,7 +741,7 @@ bool MultiplexRouter::ProcessIncomingMessage(
DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread()); DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread());
DCHECK(!paused_); DCHECK(!paused_);
DCHECK(message); DCHECK(message);
lock_.AssertAcquired(); AssertLockAcquired();
if (message->IsNull()) { if (message->IsNull()) {
// This is a sync message and has been processed during sync handle // This is a sync message and has been processed during sync handle
...@@ -811,7 +815,7 @@ bool MultiplexRouter::ProcessIncomingMessage( ...@@ -811,7 +815,7 @@ bool MultiplexRouter::ProcessIncomingMessage(
// //
// It is safe to call into |client| without the lock. Because |client| is // It is safe to call into |client| without the lock. Because |client| is
// always accessed on the same thread, including DetachEndpointClient(). // always accessed on the same thread, including DetachEndpointClient().
base::AutoUnlock unlocker(lock_); MayAutoUnlock unlocker(lock_.get());
result = client->HandleIncomingMessage(message); result = client->HandleIncomingMessage(message);
} }
if (!result) if (!result)
...@@ -822,7 +826,7 @@ bool MultiplexRouter::ProcessIncomingMessage( ...@@ -822,7 +826,7 @@ bool MultiplexRouter::ProcessIncomingMessage(
void MultiplexRouter::MaybePostToProcessTasks( void MultiplexRouter::MaybePostToProcessTasks(
base::SingleThreadTaskRunner* task_runner) { base::SingleThreadTaskRunner* task_runner) {
lock_.AssertAcquired(); AssertLockAcquired();
if (posted_to_process_tasks_) if (posted_to_process_tasks_)
return; return;
...@@ -835,7 +839,7 @@ void MultiplexRouter::MaybePostToProcessTasks( ...@@ -835,7 +839,7 @@ void MultiplexRouter::MaybePostToProcessTasks(
void MultiplexRouter::LockAndCallProcessTasks() { void MultiplexRouter::LockAndCallProcessTasks() {
// There is no need to hold a ref to this class in this case because this is // There is no need to hold a ref to this class in this case because this is
// always called using base::Bind(), which holds a ref. // always called using base::Bind(), which holds a ref.
base::AutoLock locker(lock_); MayAutoLock locker(lock_.get());
posted_to_process_tasks_ = false; posted_to_process_tasks_ = false;
scoped_refptr<base::SingleThreadTaskRunner> runner( scoped_refptr<base::SingleThreadTaskRunner> runner(
std::move(posted_to_task_runner_)); std::move(posted_to_task_runner_));
...@@ -861,7 +865,7 @@ void MultiplexRouter::UpdateEndpointStateMayRemove( ...@@ -861,7 +865,7 @@ void MultiplexRouter::UpdateEndpointStateMayRemove(
} }
void MultiplexRouter::RaiseErrorInNonTestingMode() { void MultiplexRouter::RaiseErrorInNonTestingMode() {
lock_.AssertAcquired(); AssertLockAcquired();
if (!testing_mode_) if (!testing_mode_)
RaiseError(); RaiseError();
} }
...@@ -869,7 +873,7 @@ void MultiplexRouter::RaiseErrorInNonTestingMode() { ...@@ -869,7 +873,7 @@ void MultiplexRouter::RaiseErrorInNonTestingMode() {
MultiplexRouter::InterfaceEndpoint* MultiplexRouter::FindOrInsertEndpoint( MultiplexRouter::InterfaceEndpoint* MultiplexRouter::FindOrInsertEndpoint(
InterfaceId id, InterfaceId id,
bool* inserted) { bool* inserted) {
lock_.AssertAcquired(); AssertLockAcquired();
// Either |inserted| is nullptr or it points to a boolean initialized as // Either |inserted| is nullptr or it points to a boolean initialized as
// false. // false.
DCHECK(!inserted || !*inserted); DCHECK(!inserted || !*inserted);
...@@ -888,5 +892,12 @@ MultiplexRouter::InterfaceEndpoint* MultiplexRouter::FindOrInsertEndpoint( ...@@ -888,5 +892,12 @@ MultiplexRouter::InterfaceEndpoint* MultiplexRouter::FindOrInsertEndpoint(
return endpoint; return endpoint;
} }
void MultiplexRouter::AssertLockAcquired() {
#if DCHECK_IS_ON()
if (lock_)
lock_->AssertAcquired();
#endif
}
} // namespace internal } // namespace internal
} // namespace mojo } // namespace mojo
...@@ -56,10 +56,22 @@ class MultiplexRouter ...@@ -56,10 +56,22 @@ class MultiplexRouter
public AssociatedGroupController, public AssociatedGroupController,
public PipeControlMessageHandlerDelegate { public PipeControlMessageHandlerDelegate {
public: public:
enum Config {
// There is only the master interface running on this router. Please note
// that because of interface versioning, the other side of the message pipe
// may use a newer master interface definition which passes associated
// interfaces. In that case, this router may still receive pipe control
// messages or messages targetting associated interfaces.
SINGLE_INTERFACE,
// There may be associated interfaces running on this router.
MULTI_INTERFACE
};
// If |set_interface_id_namespace_bit| is true, the interface IDs generated by // If |set_interface_id_namespace_bit| is true, the interface IDs generated by
// this router will have the highest bit set. // this router will have the highest bit set.
MultiplexRouter(bool set_interface_id_namespace_bit, MultiplexRouter(ScopedMessagePipeHandle message_pipe,
ScopedMessagePipeHandle message_pipe, Config config,
bool set_interface_id_namespace_bit,
scoped_refptr<base::SingleThreadTaskRunner> runner); scoped_refptr<base::SingleThreadTaskRunner> runner);
// Sets the master interface name for this router. Only used when reporting // Sets the master interface name for this router. Only used when reporting
...@@ -205,6 +217,8 @@ class MultiplexRouter ...@@ -205,6 +217,8 @@ class MultiplexRouter
InterfaceEndpoint* FindOrInsertEndpoint(InterfaceId id, bool* inserted); InterfaceEndpoint* FindOrInsertEndpoint(InterfaceId id, bool* inserted);
void AssertLockAcquired();
// Whether to set the namespace bit when generating interface IDs. Please see // Whether to set the namespace bit when generating interface IDs. Please see
// comments of kInterfaceIdNamespaceMask. // comments of kInterfaceIdNamespaceMask.
const bool set_interface_id_namespace_bit_; const bool set_interface_id_namespace_bit_;
...@@ -220,7 +234,8 @@ class MultiplexRouter ...@@ -220,7 +234,8 @@ class MultiplexRouter
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
// Protects the following members. // Protects the following members.
mutable base::Lock lock_; // Sets to nullptr in Config::SINGLE_INTERFACE mode.
std::unique_ptr<base::Lock> lock_;
PipeControlMessageHandler control_message_handler_; PipeControlMessageHandler control_message_handler_;
PipeControlMessageProxy control_message_proxy_; PipeControlMessageProxy control_message_proxy_;
......
...@@ -113,9 +113,11 @@ class AssociatedInterfaceTest : public testing::Test { ...@@ -113,9 +113,11 @@ class AssociatedInterfaceTest : public testing::Test {
void CreateRouterPair(scoped_refptr<MultiplexRouter>* router0, void CreateRouterPair(scoped_refptr<MultiplexRouter>* router0,
scoped_refptr<MultiplexRouter>* router1) { scoped_refptr<MultiplexRouter>* router1) {
MessagePipe pipe; MessagePipe pipe;
*router0 = new MultiplexRouter(true, std::move(pipe.handle0), *router0 = new MultiplexRouter(std::move(pipe.handle0),
MultiplexRouter::MULTI_INTERFACE, true,
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get());
*router1 = new MultiplexRouter(false, std::move(pipe.handle1), *router1 = new MultiplexRouter(std::move(pipe.handle1),
MultiplexRouter::MULTI_INTERFACE, false,
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get());
} }
......
...@@ -217,11 +217,13 @@ TEST_F(MojoBindingsPerftest, RouterPingPong) { ...@@ -217,11 +217,13 @@ TEST_F(MojoBindingsPerftest, RouterPingPong) {
TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) { TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) {
MessagePipe pipe; MessagePipe pipe;
scoped_refptr<internal::MultiplexRouter> router0( scoped_refptr<internal::MultiplexRouter> router0(
new internal::MultiplexRouter(true, std::move(pipe.handle0), new internal::MultiplexRouter(std::move(pipe.handle0),
base::ThreadTaskRunnerHandle::Get())); internal::MultiplexRouter::SINGLE_INTERFACE,
true, base::ThreadTaskRunnerHandle::Get()));
scoped_refptr<internal::MultiplexRouter> router1( scoped_refptr<internal::MultiplexRouter> router1(
new internal::MultiplexRouter(false, std::move(pipe.handle1), new internal::MultiplexRouter(
base::ThreadTaskRunnerHandle::Get())); std::move(pipe.handle1), internal::MultiplexRouter::SINGLE_INTERFACE,
false, base::ThreadTaskRunnerHandle::Get()));
PingPongPaddle paddle0(nullptr); PingPongPaddle paddle0(nullptr);
PingPongPaddle paddle1(nullptr); PingPongPaddle paddle1(nullptr);
...@@ -302,7 +304,8 @@ TEST_F(MojoBindingsPerftest, RouterDispatchCost) { ...@@ -302,7 +304,8 @@ TEST_F(MojoBindingsPerftest, RouterDispatchCost) {
TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) { TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) {
MessagePipe pipe; MessagePipe pipe;
scoped_refptr<internal::MultiplexRouter> router(new internal::MultiplexRouter( scoped_refptr<internal::MultiplexRouter> router(new internal::MultiplexRouter(
true, std::move(pipe.handle0), base::ThreadTaskRunnerHandle::Get())); std::move(pipe.handle0), internal::MultiplexRouter::SINGLE_INTERFACE,
true, base::ThreadTaskRunnerHandle::Get()));
CounterReceiver receiver; CounterReceiver receiver;
InterfaceEndpointClient client( InterfaceEndpointClient client(
router->CreateLocalEndpointHandle(kMasterInterfaceId), &receiver, nullptr, router->CreateLocalEndpointHandle(kMasterInterfaceId), &receiver, nullptr,
......
...@@ -31,9 +31,11 @@ class MultiplexRouterTest : public testing::Test { ...@@ -31,9 +31,11 @@ class MultiplexRouterTest : public testing::Test {
void SetUp() override { void SetUp() override {
MessagePipe pipe; MessagePipe pipe;
router0_ = new MultiplexRouter(true, std::move(pipe.handle0), router0_ = new MultiplexRouter(std::move(pipe.handle0),
MultiplexRouter::MULTI_INTERFACE, false,
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get());
router1_ = new MultiplexRouter(true, std::move(pipe.handle1), router1_ = new MultiplexRouter(std::move(pipe.handle1),
MultiplexRouter::MULTI_INTERFACE, true,
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get());
router0_->CreateEndpointHandlePair(&endpoint0_, &endpoint1_); router0_->CreateEndpointHandlePair(&endpoint0_, &endpoint1_);
endpoint1_ = endpoint1_ =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment