From 03f4afa8fbf7b29895b14a1d7349d7ffd6e7aafe Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Tue, 22 Jun 2021 18:17:18 +0000 Subject: [PATCH] Bug 1706374 - Part 3: Get mojo/core/ports building in libxul, r=handyman This involves replacing a number of types normally provided by chromium's `base` with their XPCOM counterparts etc. Differential Revision: https://phabricator.services.mozilla.com/D112767 --- ipc/chromium/moz.build | 8 + ipc/chromium/src/base/histogram.cc | 1 - ipc/chromium/src/base/logging.h | 2 + ipc/chromium/src/mojo/core/ports/BUILD.gn | 61 ----- ipc/chromium/src/mojo/core/ports/event.cc | 60 +++-- ipc/chromium/src/mojo/core/ports/event.h | 33 ++- .../src/mojo/core/ports/message_queue.cc | 27 +- .../src/mojo/core/ports/message_queue.h | 17 +- ipc/chromium/src/mojo/core/ports/name.cc | 8 + ipc/chromium/src/mojo/core/ports/name.h | 26 +- ipc/chromium/src/mojo/core/ports/node.cc | 239 +++++++----------- ipc/chromium/src/mojo/core/ports/node.h | 60 +++-- ipc/chromium/src/mojo/core/ports/port.h | 28 +- .../src/mojo/core/ports/port_locker.cc | 17 +- .../src/mojo/core/ports/port_locker.h | 18 +- ipc/chromium/src/mojo/core/ports/port_ref.cc | 2 +- ipc/chromium/src/mojo/core/ports/port_ref.h | 9 +- ipc/chromium/src/mojo/core/ports/user_data.h | 8 +- .../src/mojo/core/ports/user_message.h | 10 +- 19 files changed, 275 insertions(+), 359 deletions(-) delete mode 100644 ipc/chromium/src/mojo/core/ports/BUILD.gn diff --git a/ipc/chromium/moz.build b/ipc/chromium/moz.build index 62acea0547bc..e22e62afb492 100644 --- a/ipc/chromium/moz.build +++ b/ipc/chromium/moz.build @@ -29,6 +29,14 @@ UNIFIED_SOURCES += [ "src/chrome/common/chrome_switches.cc", "src/chrome/common/ipc_channel_utils.cc", "src/chrome/common/ipc_message.cc", + "src/mojo/core/ports/event.cc", + "src/mojo/core/ports/message_queue.cc", + "src/mojo/core/ports/name.cc", + "src/mojo/core/ports/node.cc", + "src/mojo/core/ports/port.cc", + "src/mojo/core/ports/port_locker.cc", + "src/mojo/core/ports/port_ref.cc", + "src/mojo/core/ports/user_message.cc", ] if os_win: diff --git a/ipc/chromium/src/base/histogram.cc b/ipc/chromium/src/base/histogram.cc index 9141eff75c3b..ffb951846615 100644 --- a/ipc/chromium/src/base/histogram.cc +++ b/ipc/chromium/src/base/histogram.cc @@ -23,7 +23,6 @@ namespace base { -#define DVLOG(x) CHROMIUM_LOG(ERROR) #define CHECK_GT DCHECK_GT #define CHECK_LT DCHECK_LT diff --git a/ipc/chromium/src/base/logging.h b/ipc/chromium/src/base/logging.h index f7bbedaa9d37..3e6250563842 100644 --- a/ipc/chromium/src/base/logging.h +++ b/ipc/chromium/src/base/logging.h @@ -106,6 +106,8 @@ const mozilla::EmptyLog& operator<<(const mozilla::EmptyLog& log, const T&) { while (false && (condition)) mozilla::EmptyLog() #endif +#define DVLOG(level) DLOG(INFO) + #undef LOG_ASSERT #define LOG_ASSERT(cond) CHECK(0) #define DLOG_ASSERT(cond) DCHECK(0) diff --git a/ipc/chromium/src/mojo/core/ports/BUILD.gn b/ipc/chromium/src/mojo/core/ports/BUILD.gn deleted file mode 100644 index 33c854b58f92..000000000000 --- a/ipc/chromium/src/mojo/core/ports/BUILD.gn +++ /dev/null @@ -1,61 +0,0 @@ -# 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. - -import("//build/config/compiler/compiler.gni") -import("//testing/test.gni") - -component("ports") { - output_name = "mojo_core_ports" - - sources = [ - "event.cc", - "event.h", - "message_filter.h", - "message_queue.cc", - "message_queue.h", - "name.cc", - "name.h", - "node.cc", - "node.h", - "node_delegate.h", - "port.cc", - "port.h", - "port_locker.cc", - "port_locker.h", - "port_ref.cc", - "port_ref.h", - "user_data.h", - "user_message.cc", - "user_message.h", - ] - - defines = [ "IS_MOJO_CORE_PORTS_IMPL" ] - - public_deps = [ "//base" ] - - if (!is_nacl) { - deps = [ "//crypto" ] - } - - if (!is_debug && !optimize_for_size) { - configs -= [ "//build/config/compiler:default_optimization" ] - configs += [ "//build/config/compiler:optimize_max" ] - } -} - -source_set("tests") { - testonly = true - - sources = [ - "name_unittest.cc", - "ports_unittest.cc", - ] - - deps = [ - ":ports", - "//base", - "//base/test:test_support", - "//testing/gtest", - ] -} diff --git a/ipc/chromium/src/mojo/core/ports/event.cc b/ipc/chromium/src/mojo/core/ports/event.cc index ce0368a305b3..bf49efc9e198 100644 --- a/ipc/chromium/src/mojo/core/ports/event.cc +++ b/ipc/chromium/src/mojo/core/ports/event.cc @@ -8,8 +8,9 @@ #include #include "base/logging.h" -#include "base/numerics/safe_math.h" #include "mojo/core/ports/user_message.h" +#include "mozilla/Assertions.h" +#include "mozilla/CheckedInt.h" namespace mojo { namespace core { @@ -156,7 +157,7 @@ UserMessageEvent::UserMessageEvent(size_t num_ports) ReservePorts(num_ports); } -void UserMessageEvent::AttachMessage(std::unique_ptr message) { +void UserMessageEvent::AttachMessage(mozilla::UniquePtr message) { DCHECK(!message_); message_ = std::move(message); } @@ -178,17 +179,16 @@ ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name, if (num_bytes < sizeof(UserMessageEventData)) return nullptr; const auto* data = static_cast(buffer); - base::CheckedNumeric port_data_size = data->num_ports; + mozilla::CheckedInt port_data_size = data->num_ports; port_data_size *= sizeof(PortDescriptor) + sizeof(PortName); - if (!port_data_size.IsValid()) return nullptr; + if (!port_data_size.isValid()) return nullptr; - base::CheckedNumeric total_size = port_data_size.ValueOrDie(); + mozilla::CheckedInt total_size = port_data_size.value(); total_size += sizeof(UserMessageEventData); - if (!total_size.IsValid() || num_bytes < total_size.ValueOrDie()) - return nullptr; + if (!total_size.isValid() || num_bytes < total_size.value()) return nullptr; auto event = - base::WrapUnique(new UserMessageEvent(port_name, data->sequence_num)); + mozilla::WrapUnique(new UserMessageEvent(port_name, data->sequence_num)); event->ReservePorts(data->num_ports); const auto* in_descriptors = reinterpret_cast(data + 1); @@ -198,7 +198,7 @@ ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name, const auto* in_names = reinterpret_cast(in_descriptors + data->num_ports); std::copy(in_names, in_names + data->num_ports, event->ports()); - return std::move(event); + return event; } UserMessageEvent::UserMessageEvent(const PortName& port_name, @@ -212,19 +212,22 @@ size_t UserMessageEvent::GetSizeIfSerialized() const { size_t UserMessageEvent::GetSerializedDataSize() const { DCHECK_EQ(ports_.size(), port_descriptors_.size()); - base::CheckedNumeric size = sizeof(UserMessageEventData); - base::CheckedNumeric ports_size = + mozilla::CheckedInt size = sizeof(UserMessageEventData); + mozilla::CheckedInt ports_size = sizeof(PortDescriptor) + sizeof(PortName); ports_size *= ports_.size(); - return (size + ports_size.ValueOrDie()).ValueOrDie(); + mozilla::CheckedInt combined = size + ports_size; + MOZ_RELEASE_ASSERT(combined.isValid()); + return combined.value(); } void UserMessageEvent::SerializeData(void* buffer) const { DCHECK_EQ(ports_.size(), port_descriptors_.size()); auto* data = static_cast(buffer); data->sequence_num = sequence_num_; - DCHECK(base::IsValueInRangeForNumericType(ports_.size())); - data->num_ports = static_cast(ports_.size()); + mozilla::CheckedInt num_ports{ports_.size()}; + DCHECK(num_ports.isValid()); + data->num_ports = num_ports.value(); data->padding = 0; auto* ports_data = reinterpret_cast(data + 1); @@ -244,7 +247,7 @@ PortAcceptedEvent::~PortAcceptedEvent() = default; ScopedEvent PortAcceptedEvent::Deserialize(const PortName& port_name, const void* buffer, size_t num_bytes) { - return std::make_unique(port_name); + return mozilla::MakeUnique(port_name); } size_t PortAcceptedEvent::GetSerializedDataSize() const { return 0; } @@ -271,7 +274,7 @@ ScopedEvent ObserveProxyEvent::Deserialize(const PortName& port_name, if (num_bytes < sizeof(ObserveProxyEventData)) return nullptr; const auto* data = static_cast(buffer); - return std::make_unique( + return mozilla::MakeUnique( port_name, data->proxy_node_name, data->proxy_port_name, data->proxy_target_node_name, data->proxy_target_port_name); } @@ -289,7 +292,7 @@ void ObserveProxyEvent::SerializeData(void* buffer) const { } ScopedEvent ObserveProxyEvent::Clone() const { - return std::make_unique( + return mozilla::MakeUnique( port_name(), proxy_node_name_, proxy_port_name_, proxy_target_node_name_, proxy_target_port_name_); } @@ -308,8 +311,8 @@ ScopedEvent ObserveProxyAckEvent::Deserialize(const PortName& port_name, if (num_bytes < sizeof(ObserveProxyAckEventData)) return nullptr; const auto* data = static_cast(buffer); - return std::make_unique(port_name, - data->last_sequence_num); + return mozilla::MakeUnique(port_name, + data->last_sequence_num); } size_t ObserveProxyAckEvent::GetSerializedDataSize() const { @@ -322,8 +325,8 @@ void ObserveProxyAckEvent::SerializeData(void* buffer) const { } ScopedEvent ObserveProxyAckEvent::Clone() const { - return std::make_unique(port_name(), - last_sequence_num_); + return mozilla::MakeUnique(port_name(), + last_sequence_num_); } ObserveClosureEvent::ObserveClosureEvent(const PortName& port_name, @@ -340,8 +343,8 @@ ScopedEvent ObserveClosureEvent::Deserialize(const PortName& port_name, if (num_bytes < sizeof(ObserveClosureEventData)) return nullptr; const auto* data = static_cast(buffer); - return std::make_unique(port_name, - data->last_sequence_num); + return mozilla::MakeUnique(port_name, + data->last_sequence_num); } size_t ObserveClosureEvent::GetSerializedDataSize() const { @@ -354,7 +357,8 @@ void ObserveClosureEvent::SerializeData(void* buffer) const { } ScopedEvent ObserveClosureEvent::Clone() const { - return std::make_unique(port_name(), last_sequence_num_); + return mozilla::MakeUnique(port_name(), + last_sequence_num_); } MergePortEvent::MergePortEvent(const PortName& port_name, @@ -372,8 +376,8 @@ ScopedEvent MergePortEvent::Deserialize(const PortName& port_name, if (num_bytes < sizeof(MergePortEventData)) return nullptr; const auto* data = static_cast(buffer); - return std::make_unique(port_name, data->new_port_name, - data->new_port_descriptor); + return mozilla::MakeUnique(port_name, data->new_port_name, + data->new_port_descriptor); } size_t MergePortEvent::GetSerializedDataSize() const { @@ -400,7 +404,7 @@ ScopedEvent UserMessageReadAckRequestEvent::Deserialize( const auto* data = static_cast(buffer); - return std::make_unique( + return mozilla::MakeUnique( port_name, data->sequence_num_to_acknowledge); } @@ -427,7 +431,7 @@ ScopedEvent UserMessageReadAckEvent::Deserialize(const PortName& port_name, if (num_bytes < sizeof(UserMessageReadAckEventData)) return nullptr; const auto* data = static_cast(buffer); - return std::make_unique( + return mozilla::MakeUnique( port_name, data->sequence_num_acknowledged); } diff --git a/ipc/chromium/src/mojo/core/ports/event.h b/ipc/chromium/src/mojo/core/ports/event.h index 9b197931d0eb..e18e3d63ea86 100644 --- a/ipc/chromium/src/mojo/core/ports/event.h +++ b/ipc/chromium/src/mojo/core/ports/event.h @@ -7,11 +7,9 @@ #include +#include #include -#include "base/component_export.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" #include "mojo/core/ports/name.h" #include "mojo/core/ports/user_message.h" @@ -21,11 +19,11 @@ namespace ports { class Event; -using ScopedEvent = std::unique_ptr; +using ScopedEvent = mozilla::UniquePtr; // A Event is the fundamental unit of operation and communication within and // between Nodes. -class COMPONENT_EXPORT(MOJO_CORE_PORTS) Event { +class Event { public: enum Type : uint32_t { // A user message event contains arbitrary user-specified payload data @@ -85,8 +83,8 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Event { static ScopedEvent Deserialize(const void* buffer, size_t num_bytes); template - static std::unique_ptr Cast(ScopedEvent* event) { - return base::WrapUnique(static_cast(event->release())); + static mozilla::UniquePtr Cast(ScopedEvent* event) { + return mozilla::WrapUnique(static_cast(event->release())); } Type type() const { return type_; } @@ -110,13 +108,13 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Event { DISALLOW_COPY_AND_ASSIGN(Event); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event { +class UserMessageEvent : public Event { public: explicit UserMessageEvent(size_t num_ports); ~UserMessageEvent() override; bool HasMessage() const { return !!message_; } - void AttachMessage(std::unique_ptr message); + void AttachMessage(mozilla::UniquePtr message); template T* GetMessage() { @@ -156,12 +154,12 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event { uint64_t sequence_num_ = 0; std::vector port_descriptors_; std::vector ports_; - std::unique_ptr message_; + mozilla::UniquePtr message_; DISALLOW_COPY_AND_ASSIGN(UserMessageEvent); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortAcceptedEvent : public Event { +class PortAcceptedEvent : public Event { public: explicit PortAcceptedEvent(const PortName& port_name); ~PortAcceptedEvent() override; @@ -176,7 +174,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortAcceptedEvent : public Event { DISALLOW_COPY_AND_ASSIGN(PortAcceptedEvent); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyEvent : public Event { +class ObserveProxyEvent : public Event { public: ObserveProxyEvent(const PortName& port_name, const NodeName& proxy_node_name, const PortName& proxy_port_name, @@ -209,7 +207,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyEvent : public Event { DISALLOW_COPY_AND_ASSIGN(ObserveProxyEvent); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyAckEvent : public Event { +class ObserveProxyAckEvent : public Event { public: ObserveProxyAckEvent(const PortName& port_name, uint64_t last_sequence_num); ~ObserveProxyAckEvent() override; @@ -229,7 +227,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyAckEvent : public Event { DISALLOW_COPY_AND_ASSIGN(ObserveProxyAckEvent); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveClosureEvent : public Event { +class ObserveClosureEvent : public Event { public: ObserveClosureEvent(const PortName& port_name, uint64_t last_sequence_num); ~ObserveClosureEvent() override; @@ -252,7 +250,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveClosureEvent : public Event { DISALLOW_COPY_AND_ASSIGN(ObserveClosureEvent); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) MergePortEvent : public Event { +class MergePortEvent : public Event { public: MergePortEvent(const PortName& port_name, const PortName& new_port_name, const PortDescriptor& new_port_descriptor); @@ -276,8 +274,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) MergePortEvent : public Event { DISALLOW_COPY_AND_ASSIGN(MergePortEvent); }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckRequestEvent - : public Event { +class UserMessageReadAckRequestEvent : public Event { public: UserMessageReadAckRequestEvent(const PortName& port_name, uint64_t sequence_num_to_acknowledge); @@ -297,7 +294,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckRequestEvent uint64_t sequence_num_to_acknowledge_; }; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckEvent : public Event { +class UserMessageReadAckEvent : public Event { public: UserMessageReadAckEvent(const PortName& port_name, uint64_t sequence_num_acknowledged); diff --git a/ipc/chromium/src/mojo/core/ports/message_queue.cc b/ipc/chromium/src/mojo/core/ports/message_queue.cc index f519bf6f29ce..0e785bec2b0e 100644 --- a/ipc/chromium/src/mojo/core/ports/message_queue.cc +++ b/ipc/chromium/src/mojo/core/ports/message_queue.cc @@ -9,14 +9,15 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "mojo/core/ports/message_filter.h" +#include "mozilla/Likely.h" namespace mojo { namespace core { namespace ports { // Used by std::{push,pop}_heap functions -inline bool operator<(const std::unique_ptr& a, - const std::unique_ptr& b) { +inline bool operator<(const mozilla::UniquePtr& a, + const mozilla::UniquePtr& b) { return a->sequence_num() > b->sequence_num(); } @@ -29,11 +30,15 @@ MessageQueue::MessageQueue(uint64_t next_sequence_num) } MessageQueue::~MessageQueue() { -#if DCHECK_IS_ON() +#ifdef DEBUG size_t num_leaked_ports = 0; - for (const auto& message : heap_) num_leaked_ports += message->num_ports(); - DVLOG_IF(1, num_leaked_ports > 0) - << "Leaking " << num_leaked_ports << " ports in unreceived messages"; + for (const auto& message : heap_) { + num_leaked_ports += message->num_ports(); + } + if (num_leaked_ports > 0) { + DVLOG(1) << "Leaking " << num_leaked_ports + << " ports in unreceived messages"; + } #endif } @@ -41,7 +46,7 @@ bool MessageQueue::HasNextMessage() const { return !heap_.empty() && heap_[0]->sequence_num() == next_sequence_num_; } -void MessageQueue::GetNextMessage(std::unique_ptr* message, +void MessageQueue::GetNextMessage(mozilla::UniquePtr* message, MessageFilter* filter) { if (!HasNextMessage() || (filter && !filter->Match(*heap_[0]))) { message->reset(); @@ -58,15 +63,15 @@ void MessageQueue::GetNextMessage(std::unique_ptr* message, // here is somewhat arbitrary. constexpr size_t kHeapMinimumShrinkSize = 16; constexpr size_t kHeapShrinkInterval = 512; - if (UNLIKELY(heap_.size() > kHeapMinimumShrinkSize && - heap_.size() % kHeapShrinkInterval == 0)) { + if (MOZ_UNLIKELY(heap_.size() > kHeapMinimumShrinkSize && + heap_.size() % kHeapShrinkInterval == 0)) { heap_.shrink_to_fit(); } next_sequence_num_++; } -void MessageQueue::AcceptMessage(std::unique_ptr message, +void MessageQueue::AcceptMessage(mozilla::UniquePtr message, bool* has_next_message) { // TODO: Handle sequence number roll-over. @@ -82,7 +87,7 @@ void MessageQueue::AcceptMessage(std::unique_ptr message, } void MessageQueue::TakeAllMessages( - std::vector>* messages) { + std::vector>* messages) { *messages = std::move(heap_); total_queued_bytes_ = 0; } diff --git a/ipc/chromium/src/mojo/core/ports/message_queue.h b/ipc/chromium/src/mojo/core/ports/message_queue.h index 1d34222c5eb5..a9e08c761a51 100644 --- a/ipc/chromium/src/mojo/core/ports/message_queue.h +++ b/ipc/chromium/src/mojo/core/ports/message_queue.h @@ -11,8 +11,6 @@ #include #include -#include "base/component_export.h" -#include "base/macros.h" #include "mojo/core/ports/event.h" namespace mojo { @@ -28,12 +26,15 @@ class MessageFilter; // known sequence number and can indicate whether the next sequential message is // available. Thus the queue enforces message ordering for the consumer without // enforcing it for the producer (see AcceptMessage() below.) -class COMPONENT_EXPORT(MOJO_CORE_PORTS) MessageQueue { +class MessageQueue { public: explicit MessageQueue(); explicit MessageQueue(uint64_t next_sequence_num); ~MessageQueue(); + MessageQueue(const MessageQueue&) = delete; + void operator=(const MessageQueue&) = delete; + void set_signalable(bool value) { signalable_ = value; } uint64_t next_sequence_num() const { return next_sequence_num_; } @@ -42,7 +43,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) MessageQueue { // Gives ownership of the message. If |filter| is non-null, the next message // will only be retrieved if the filter successfully matches it. - void GetNextMessage(std::unique_ptr* message, + void GetNextMessage(mozilla::UniquePtr* message, MessageFilter* filter); // Takes ownership of the message. Note: Messages are ordered, so while we @@ -54,13 +55,13 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) MessageQueue { // until GetNextMessage is called enough times to return a null message. // In other words, has_next_message acts like an edge trigger. // - void AcceptMessage(std::unique_ptr message, + void AcceptMessage(mozilla::UniquePtr message, bool* has_next_message); // Takes all messages from this queue. Used to safely destroy queued messages // without holding any Port lock. void TakeAllMessages( - std::vector>* messages); + std::vector>* messages); // The number of messages queued here, regardless of whether the next expected // message has arrived yet. @@ -71,12 +72,10 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) MessageQueue { size_t queued_num_bytes() const { return total_queued_bytes_; } private: - std::vector> heap_; + std::vector> heap_; uint64_t next_sequence_num_; bool signalable_ = true; size_t total_queued_bytes_ = 0; - - DISALLOW_COPY_AND_ASSIGN(MessageQueue); }; } // namespace ports diff --git a/ipc/chromium/src/mojo/core/ports/name.cc b/ipc/chromium/src/mojo/core/ports/name.cc index 7993fa34c8f1..d0f12090d178 100644 --- a/ipc/chromium/src/mojo/core/ports/name.cc +++ b/ipc/chromium/src/mojo/core/ports/name.cc @@ -20,6 +20,14 @@ std::ostream& operator<<(std::ostream& stream, const Name& name) { return stream; } +mozilla::Logger& operator<<(mozilla::Logger& log, const Name& name) { + log.printf("%" PRIX64, name.v1); + if (name.v2 != 0) { + log.printf(".%" PRIX64, name.v2); + } + return log; +} + } // namespace ports } // namespace core } // namespace mojo diff --git a/ipc/chromium/src/mojo/core/ports/name.h b/ipc/chromium/src/mojo/core/ports/name.h index 9816fe0fe1d7..1085ac53c583 100644 --- a/ipc/chromium/src/mojo/core/ports/name.h +++ b/ipc/chromium/src/mojo/core/ports/name.h @@ -10,14 +10,14 @@ #include #include -#include "base/component_export.h" -#include "base/hash/hash.h" +#include "base/logging.h" +#include "mozilla/HashFunctions.h" namespace mojo { namespace core { namespace ports { -struct COMPONENT_EXPORT(MOJO_CORE_PORTS) Name { +struct Name { Name(uint64_t v1, uint64_t v2) : v1(v1), v2(v2) {} uint64_t v1, v2; }; @@ -32,22 +32,22 @@ inline bool operator<(const Name& a, const Name& b) { return std::tie(a.v1, a.v2) < std::tie(b.v1, b.v2); } -COMPONENT_EXPORT(MOJO_CORE_PORTS) std::ostream& operator<<(std::ostream& stream, const Name& name); +mozilla::Logger& operator<<(mozilla::Logger& log, const Name& name); -struct COMPONENT_EXPORT(MOJO_CORE_PORTS) PortName : Name { +struct PortName : Name { PortName() : Name(0, 0) {} PortName(uint64_t v1, uint64_t v2) : Name(v1, v2) {} }; -extern COMPONENT_EXPORT(MOJO_CORE_PORTS) const PortName kInvalidPortName; +extern const PortName kInvalidPortName; -struct COMPONENT_EXPORT(MOJO_CORE_PORTS) NodeName : Name { +struct NodeName : Name { NodeName() : Name(0, 0) {} NodeName(uint64_t v1, uint64_t v2) : Name(v1, v2) {} }; -extern COMPONENT_EXPORT(MOJO_CORE_PORTS) const NodeName kInvalidNodeName; +extern const NodeName kInvalidNodeName; } // namespace ports } // namespace core @@ -56,16 +56,18 @@ extern COMPONENT_EXPORT(MOJO_CORE_PORTS) const NodeName kInvalidNodeName; namespace std { template <> -struct COMPONENT_EXPORT(MOJO_CORE_PORTS) hash { +struct hash { std::size_t operator()(const mojo::core::ports::PortName& name) const { - return base::HashInts64(name.v1, name.v2); + // FIXME: HashGeneric only generates a 32-bit hash + return mozilla::HashGeneric(name.v1, name.v2); } }; template <> -struct COMPONENT_EXPORT(MOJO_CORE_PORTS) hash { +struct hash { std::size_t operator()(const mojo::core::ports::NodeName& name) const { - return base::HashInts64(name.v1, name.v2); + // FIXME: HashGeneric only generates a 32-bit hash + return mozilla::HashGeneric(name.v1, name.v2); } }; diff --git a/ipc/chromium/src/mojo/core/ports/node.cc b/ipc/chromium/src/mojo/core/ports/node.cc index de246dcbf764..cf0e48422985 100644 --- a/ipc/chromium/src/mojo/core/ports/node.cc +++ b/ipc/chromium/src/mojo/core/ports/node.cc @@ -12,69 +12,21 @@ #include #include -#include "base/containers/stack_container.h" -#include "base/lazy_instance.h" +#include "mozilla/Mutex.h" +#include "mozilla/RandomNum.h" +#include "nsTArray.h" + #include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/notreached.h" -#include "base/optional.h" -#include "base/synchronization/lock.h" -#include "base/threading/thread_local.h" -#include "build/build_config.h" #include "mojo/core/ports/event.h" #include "mojo/core/ports/node_delegate.h" #include "mojo/core/ports/port_locker.h" -#if !defined(OS_NACL) -# include "crypto/random.h" -#else -# include "base/rand_util.h" -#endif - namespace mojo { namespace core { namespace ports { namespace { -constexpr size_t kRandomNameCacheSize = 256; - -// Random port name generator which maintains a cache of random bytes to draw -// from. This amortizes the cost of random name generation on platforms where -// RandBytes may have significant per-call overhead. -// -// Note that the use of this cache means one has to be careful about fork()ing -// a process once any port names have been generated, as that behavior can lead -// to collisions between independently generated names in different processes. -class RandomNameGenerator { - public: - RandomNameGenerator() = default; - ~RandomNameGenerator() = default; - - PortName GenerateRandomPortName() { - base::AutoLock lock(lock_); - if (cache_index_ == kRandomNameCacheSize) { -#if defined(OS_NACL) - base::RandBytes(cache_, sizeof(PortName) * kRandomNameCacheSize); -#else - crypto::RandBytes(cache_, sizeof(PortName) * kRandomNameCacheSize); -#endif - cache_index_ = 0; - } - return cache_[cache_index_++]; - } - - private: - base::Lock lock_; - PortName cache_[kRandomNameCacheSize]; - size_t cache_index_ = kRandomNameCacheSize; - - DISALLOW_COPY_AND_ASSIGN(RandomNameGenerator); -}; - -base::LazyInstance::Leaky g_name_generator = - LAZY_INSTANCE_INITIALIZER; - int DebugError(const char* message, int error_code) { NOTREACHED() << "Oops: " << message; return error_code; @@ -97,7 +49,10 @@ bool CanAcceptMoreMessages(const Port* port) { } void GenerateRandomPortName(PortName* name) { - *name = g_name_generator.Get().GenerateRandomPortName(); + // FIXME: Chrome uses a cache to avoid extra calls to the system RNG when + // generating port names to keep this overhead down. If this method starts + // showing up on profiles we should consider doing the same. + *name = PortName{mozilla::RandomUint64OrDie(), mozilla::RandomUint64OrDie()}; } } // namespace @@ -111,10 +66,10 @@ Node::~Node() { bool Node::CanShutdownCleanly(ShutdownPolicy policy) { PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_lock(ports_lock_); + mozilla::MutexAutoLock ports_lock(ports_lock_); if (policy == ShutdownPolicy::DONT_ALLOW_LOCAL_PORTS) { -#if DCHECK_IS_ON() +#ifdef DEBUG for (auto& entry : ports_) { DVLOG(2) << "Port " << entry.first << " referencing node " << entry.second->peer_node_name << " is blocking shutdown of " @@ -136,7 +91,7 @@ bool Node::CanShutdownCleanly(ShutdownPolicy policy) { auto* port = locker.port(); if (port->peer_node_name != name_ && port->state != Port::kReceiving) { can_shutdown = false; -#if DCHECK_IS_ON() +#ifdef DEBUG DVLOG(2) << "Port " << entry.first << " referencing node " << port->peer_node_name << " is blocking shutdown of " << "node " << name_ << " (state=" << port->state << ")"; @@ -152,7 +107,7 @@ bool Node::CanShutdownCleanly(ShutdownPolicy policy) { int Node::GetPort(const PortName& port_name, PortRef* port_ref) { PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock lock(ports_lock_); + mozilla::MutexAutoLock lock(ports_lock_); auto iter = ports_.find(port_name); if (iter == ports_.end()) return ERROR_PORT_UNKNOWN; @@ -169,7 +124,7 @@ int Node::CreateUninitializedPort(PortRef* port_ref) { PortName port_name; GenerateRandomPortName(&port_name); - scoped_refptr port(new Port(kInitialSequenceNum, kInitialSequenceNum)); + RefPtr port(new Port(kInitialSequenceNum, kInitialSequenceNum)); int rv = AddPortWithName(port_name, port); if (rv != OK) return rv; @@ -183,7 +138,7 @@ int Node::InitializePort(const PortRef& port_ref, { // Must be acquired for UpdatePortPeerAddress below. PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_locker(ports_lock_); + mozilla::MutexAutoLock ports_lock(ports_lock_); SinglePortLocker locker(&port_ref); auto* port = locker.port(); @@ -217,8 +172,7 @@ int Node::CreatePortPair(PortRef* port0_ref, PortRef* port1_ref) { return OK; } -int Node::SetUserData(const PortRef& port_ref, - scoped_refptr user_data) { +int Node::SetUserData(const PortRef& port_ref, RefPtr user_data) { SinglePortLocker locker(&port_ref); auto* port = locker.port(); if (port->state == Port::kClosed) return ERROR_PORT_STATE_UNEXPECTED; @@ -228,8 +182,7 @@ int Node::SetUserData(const PortRef& port_ref, return OK; } -int Node::GetUserData(const PortRef& port_ref, - scoped_refptr* user_data) { +int Node::GetUserData(const PortRef& port_ref, RefPtr* user_data) { SinglePortLocker locker(&port_ref); auto* port = locker.port(); if (port->state == Port::kClosed) return ERROR_PORT_STATE_UNEXPECTED; @@ -240,7 +193,7 @@ int Node::GetUserData(const PortRef& port_ref, } int Node::ClosePort(const PortRef& port_ref) { - std::vector> undelivered_messages; + std::vector> undelivered_messages; NodeName peer_node_name; PortName peer_port_name; uint64_t last_sequence_num = 0; @@ -280,7 +233,7 @@ int Node::ClosePort(const PortRef& port_ref) { DVLOG(2) << "Sending ObserveClosure from " << port_ref.name() << "@" << name_ << " to " << peer_port_name << "@" << peer_node_name; delegate_->ForwardEvent(peer_node_name, - std::make_unique( + mozilla::MakeUnique( peer_port_name, last_sequence_num)); for (const auto& message : undelivered_messages) { for (size_t i = 0; i < message->num_ports(); ++i) { @@ -312,7 +265,7 @@ int Node::GetStatus(const PortRef& port_ref, PortStatus* port_status) { } int Node::GetMessage(const PortRef& port_ref, - std::unique_ptr* message, + mozilla::UniquePtr* message, MessageFilter* filter) { *message = nullptr; @@ -336,7 +289,7 @@ int Node::GetMessage(const PortRef& port_ref, if (*message && (*message)->sequence_num() == port->sequence_num_to_acknowledge) { peer_node_name = port->peer_node_name; - ack_event = std::make_unique( + ack_event = mozilla::MakeUnique( port->peer_port_name, port->sequence_num_to_acknowledge); } } @@ -366,7 +319,7 @@ int Node::GetMessage(const PortRef& port_ref, } int Node::SendUserMessage(const PortRef& port_ref, - std::unique_ptr message) { + mozilla::UniquePtr message) { int rv = SendUserMessageInternal(port_ref, &message); if (rv != OK) { // If send failed, close all carried ports. Note that we're careful not to @@ -403,7 +356,7 @@ int Node::SetAcknowledgeRequestInterval( } delegate_->ForwardEvent(peer_node_name, - std::make_unique( + mozilla::MakeUnique( peer_port_name, sequence_num_to_request_ack)); return OK; } @@ -439,7 +392,7 @@ int Node::MergePorts(const PortRef& port_ref, { // Must be held for ConvertToProxy. PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_locker(ports_lock_); + mozilla::MutexAutoLock ports_locker(ports_lock_); SinglePortLocker locker(&port_ref); @@ -464,8 +417,8 @@ int Node::MergePorts(const PortRef& port_ref, delegate_->ForwardEvent( destination_node_name, - std::make_unique(destination_port_name, new_port_name, - new_port_descriptor)); + mozilla::MakeUnique(destination_port_name, new_port_name, + new_port_descriptor)); return OK; } @@ -487,10 +440,10 @@ int Node::LostConnectionToNode(const NodeName& node_name) { return OK; } -int Node::OnUserMessage(std::unique_ptr message) { +int Node::OnUserMessage(mozilla::UniquePtr message) { PortName port_name = message->port_name(); -#if DCHECK_IS_ON() +#ifdef DEBUG std::ostringstream ports_buf; for (size_t i = 0; i < message->num_ports(); ++i) { if (i > 0) ports_buf << ","; @@ -574,11 +527,11 @@ int Node::OnUserMessage(std::unique_ptr message) { return OK; } -int Node::OnPortAccepted(std::unique_ptr event) { +int Node::OnPortAccepted(mozilla::UniquePtr event) { PortRef port_ref; if (GetPort(event->port_name(), &port_ref) != OK) return ERROR_PORT_UNKNOWN; -#if DCHECK_IS_ON() +#ifdef DEBUG { SinglePortLocker locker(&port_ref); DVLOG(2) << "PortAccepted at " << port_ref.name() << "@" << name_ @@ -590,7 +543,7 @@ int Node::OnPortAccepted(std::unique_ptr event) { return BeginProxying(port_ref); } -int Node::OnObserveProxy(std::unique_ptr event) { +int Node::OnObserveProxy(mozilla::UniquePtr event) { if (event->port_name() == kInvalidPortName) { // An ObserveProxy with an invalid target port name is a broadcast used to // inform ports when their peer (which was itself a proxy) has become @@ -627,7 +580,7 @@ int Node::OnObserveProxy(std::unique_ptr event) { { // Must be acquired for UpdatePortPeerAddress below. PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_locker(ports_lock_); + mozilla::MutexAutoLock ports_locker(ports_lock_); SinglePortLocker locker(&port_ref); auto* port = locker.port(); @@ -639,7 +592,7 @@ int Node::OnObserveProxy(std::unique_ptr event) { event->proxy_target_node_name(), event->proxy_target_port_name()); event_target_node = event->proxy_node_name(); - event_to_forward = std::make_unique( + event_to_forward = mozilla::MakeUnique( event->proxy_port_name(), port->next_sequence_num_to_send - 1); peer_changed = true; DVLOG(2) << "Forwarding ObserveProxyAck from " << event->port_name() @@ -660,10 +613,10 @@ int Node::OnObserveProxy(std::unique_ptr event) { << "@" << event->proxy_node_name(); port->send_on_proxy_removal = - std::make_unique>( + mozilla::MakeUnique>( event->proxy_node_name(), - std::make_unique(event->proxy_port_name(), - kInvalidSequenceNum)); + mozilla::MakeUnique( + event->proxy_port_name(), kInvalidSequenceNum)); } } else { // Forward this event along to our peer. Eventually, it should find the @@ -689,7 +642,7 @@ int Node::OnObserveProxy(std::unique_ptr event) { return OK; } -int Node::OnObserveProxyAck(std::unique_ptr event) { +int Node::OnObserveProxyAck(mozilla::UniquePtr event) { DVLOG(2) << "ObserveProxyAck at " << event->port_name() << "@" << name_ << " (last_sequence_num=" << event->last_sequence_num() << ")"; @@ -725,7 +678,7 @@ int Node::OnObserveProxyAck(std::unique_ptr event) { return OK; } -int Node::OnObserveClosure(std::unique_ptr event) { +int Node::OnObserveClosure(mozilla::UniquePtr event) { // OK if the port doesn't exist, as it may have been closed already. PortRef port_ref; if (GetPort(event->port_name(), &port_ref) != OK) return OK; @@ -799,7 +752,7 @@ int Node::OnObserveClosure(std::unique_ptr event) { return OK; } -int Node::OnMergePort(std::unique_ptr event) { +int Node::OnMergePort(mozilla::UniquePtr event) { PortRef port_ref; GetPort(event->port_name(), &port_ref); @@ -835,7 +788,7 @@ int Node::OnMergePort(std::unique_ptr event) { } int Node::OnUserMessageReadAckRequest( - std::unique_ptr event) { + mozilla::UniquePtr event) { PortRef port_ref; GetPort(event->port_name(), &port_ref); @@ -845,7 +798,7 @@ int Node::OnUserMessageReadAckRequest( if (!port_ref.is_valid()) return ERROR_PORT_UNKNOWN; NodeName peer_node_name; - std::unique_ptr event_to_send; + mozilla::UniquePtr event_to_send; { SinglePortLocker locker(&port_ref); auto* port = locker.port(); @@ -863,7 +816,7 @@ int Node::OnUserMessageReadAckRequest( if (current_sequence_num >= event->sequence_num_to_acknowledge()) { // If the current sequence number to read already exceeds the ack // request, send an ack immediately. - event_to_send = std::make_unique( + event_to_send = mozilla::MakeUnique( port->peer_port_name, current_sequence_num); // This might be a late or duplicate acknowledge request, that's @@ -897,7 +850,8 @@ int Node::OnUserMessageReadAckRequest( return OK; } -int Node::OnUserMessageReadAck(std::unique_ptr event) { +int Node::OnUserMessageReadAck( + mozilla::UniquePtr event) { PortRef port_ref; GetPort(event->port_name(), &port_ref); @@ -929,7 +883,7 @@ int Node::OnUserMessageReadAck(std::unique_ptr event) { // not been closed. if (port->sequence_num_acknowledge_interval && !port->peer_closed) { peer_node_name = port->peer_node_name; - ack_request_event = std::make_unique( + ack_request_event = mozilla::MakeUnique( port->peer_port_name, port->last_sequence_num_acknowledged + port->sequence_num_acknowledge_interval); } @@ -942,9 +896,9 @@ int Node::OnUserMessageReadAck(std::unique_ptr event) { return OK; } -int Node::AddPortWithName(const PortName& port_name, scoped_refptr port) { +int Node::AddPortWithName(const PortName& port_name, RefPtr port) { PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock lock(ports_lock_); + mozilla::MutexAutoLock lock(ports_lock_); if (port->peer_port_name != kInvalidPortName) { DCHECK_NE(kInvalidNodeName, port->peer_node_name); peer_port_maps_[port->peer_node_name][port->peer_port_name].emplace( @@ -958,9 +912,9 @@ int Node::AddPortWithName(const PortName& port_name, scoped_refptr port) { void Node::ErasePort(const PortName& port_name) { PortLocker::AssertNoPortsLockedOnCurrentThread(); - scoped_refptr port; + RefPtr port; { - base::AutoLock lock(ports_lock_); + mozilla::MutexAutoLock lock(ports_lock_); auto it = ports_.find(port_name); if (it == ports_.end()) return; port = std::move(it->second); @@ -970,7 +924,7 @@ void Node::ErasePort(const PortName& port_name) { } // NOTE: We are careful not to release the port's messages while holding any // locks, since they may run arbitrary user code upon destruction. - std::vector> messages; + std::vector> messages; { PortRef port_ref(port_name, std::move(port)); SinglePortLocker locker(&port_ref); @@ -979,9 +933,9 @@ void Node::ErasePort(const PortName& port_name) { DVLOG(2) << "Deleted port " << port_name << "@" << name_; } -int Node::SendUserMessageInternal(const PortRef& port_ref, - std::unique_ptr* message) { - std::unique_ptr& m = *message; +int Node::SendUserMessageInternal( + const PortRef& port_ref, mozilla::UniquePtr* message) { + mozilla::UniquePtr& m = *message; for (size_t i = 0; i < m->num_ports(); ++i) { if (m->ports()[i] == port_ref.name()) return ERROR_PORT_CANNOT_SEND_SELF; } @@ -1018,9 +972,10 @@ int Node::MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref, { // Needed to swap peer map entries below. PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::ReleasableAutoLock ports_locker(&ports_lock_); + mozilla::Maybe ports_locker(std::in_place, + ports_lock_); - base::Optional locker(base::in_place, port_refs, 2); + mozilla::Maybe locker(std::in_place, port_refs, size_t(2)); auto* port0 = locker->GetPort(port0_ref); auto* port1 = locker->GetPort(port1_ref); @@ -1049,7 +1004,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref, const bool close_port1 = port1->state == Port::kReceiving || allow_close_on_bad_state; locker.reset(); - ports_locker.Release(); + ports_locker.reset(); if (close_port0) ClosePort(port0_ref); if (close_port1) ClosePort(port1_ref); return ERROR_PORT_STATE_UNEXPECTED; @@ -1080,7 +1035,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref, // If either end of the port cycle is closed, we propagate an // ObserveClosure event. closure_event_target_node = port->peer_node_name; - closure_event = std::make_unique( + closure_event = mozilla::MakeUnique( port->peer_port_name, port->last_sequence_num_to_receive); } } @@ -1102,7 +1057,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref, // consistent state by undoing the peer swap and closing the ports. { PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_locker(ports_lock_); + mozilla::MutexAutoLock ports_locker(ports_lock_); PortLocker locker(port_refs, 2); auto* port0 = locker.GetPort(port0_ref); auto* port1 = locker.GetPort(port1_ref); @@ -1158,9 +1113,9 @@ void Node::ConvertToProxy(Port* port, const NodeName& to_node_name, int Node::AcceptPort(const PortName& port_name, const Event::PortDescriptor& port_descriptor) { - scoped_refptr port = - base::MakeRefCounted(port_descriptor.next_sequence_num_to_send, - port_descriptor.next_sequence_num_to_receive); + RefPtr port = + mozilla::MakeRefPtr(port_descriptor.next_sequence_num_to_send, + port_descriptor.next_sequence_num_to_receive); port->state = Port::kReceiving; port->peer_node_name = port_descriptor.peer_node_name; port->peer_port_name = port_descriptor.peer_port_name; @@ -1181,9 +1136,9 @@ int Node::AcceptPort(const PortName& port_name, if (rv != OK) return rv; // Allow referring port to forward messages. - delegate_->ForwardEvent( - port_descriptor.referring_node_name, - std::make_unique(port_descriptor.referring_port_name)); + delegate_->ForwardEvent(port_descriptor.referring_node_name, + mozilla::MakeUnique( + port_descriptor.referring_port_name)); return OK; } @@ -1204,30 +1159,31 @@ int Node::PrepareToForwardUserMessage(const PortRef& forwarding_port_ref, // it only while no port locks are held on the calling thread. if (target_node_name != name_) { if (!message->NotifyWillBeRoutedExternally()) { - LOG(ERROR) << "NotifyWillBeRoutedExternally failed unexpectedly."; + CHROMIUM_LOG(ERROR) + << "NotifyWillBeRoutedExternally failed unexpectedly."; return ERROR_PORT_STATE_UNEXPECTED; } } // Must be held because ConvertToProxy needs to update |peer_port_maps_|. PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_locker(ports_lock_); + mozilla::MutexAutoLock ports_locker(ports_lock_); // Simultaneously lock the forwarding port as well as all attached ports. - base::StackVector attached_port_refs; - base::StackVector ports_to_lock; - attached_port_refs.container().resize(message->num_ports()); - ports_to_lock.container().resize(message->num_ports() + 1); - ports_to_lock[0] = &forwarding_port_ref; + AutoTArray attached_port_refs; + AutoTArray ports_to_lock; + attached_port_refs.SetCapacity(message->num_ports()); + ports_to_lock.SetCapacity(message->num_ports() + 1); + ports_to_lock.AppendElement(&forwarding_port_ref); for (size_t i = 0; i < message->num_ports(); ++i) { const PortName& attached_port_name = message->ports()[i]; auto iter = ports_.find(attached_port_name); DCHECK(iter != ports_.end()); - attached_port_refs[i] = PortRef(attached_port_name, iter->second); - ports_to_lock[i + 1] = &attached_port_refs[i]; + attached_port_refs.AppendElement( + PortRef(attached_port_name, iter->second)); + ports_to_lock.AppendElement(&attached_port_refs[i]); } - PortLocker locker(ports_to_lock.container().data(), - ports_to_lock.container().size()); + PortLocker locker(ports_to_lock.Elements(), ports_to_lock.Length()); auto* forwarding_port = locker.GetPort(forwarding_port_ref); if (forwarding_port->peer_node_name != target_node_name) { @@ -1251,7 +1207,7 @@ int Node::PrepareToForwardUserMessage(const PortRef& forwarding_port_ref, // a proxy. Otherwise, use the next outgoing sequence number. if (message->sequence_num() == 0) message->set_sequence_num(forwarding_port->next_sequence_num_to_send++); -#if DCHECK_IS_ON() +#ifdef DEBUG std::ostringstream ports_buf; for (size_t i = 0; i < message->num_ports(); ++i) { if (i > 0) ports_buf << ","; @@ -1263,7 +1219,7 @@ int Node::PrepareToForwardUserMessage(const PortRef& forwarding_port_ref, // Sanity check to make sure we can actually send all the attached ports. // They must all be in the |kReceiving| state and must not be the sender's // own peer. - DCHECK_EQ(message->num_ports(), attached_port_refs.container().size()); + DCHECK_EQ(message->num_ports(), attached_port_refs.Length()); for (size_t i = 0; i < message->num_ports(); ++i) { auto* attached_port = locker.GetPort(attached_port_refs[i]); int error = OK; @@ -1296,7 +1252,7 @@ int Node::PrepareToForwardUserMessage(const PortRef& forwarding_port_ref, } } -#if DCHECK_IS_ON() +#ifdef DEBUG DVLOG(4) << "Sending message " << message->sequence_num() << " [ports=" << ports_buf.str() << "]" << " from " << forwarding_port_ref.name() << "@" << name_ << " to " @@ -1353,7 +1309,7 @@ int Node::BeginProxying(const PortRef& port_ref) { if (try_remove_proxy_immediately) { // Make sure we propagate closure to our current peer. closure_target_node = port->peer_node_name; - closure_event = std::make_unique( + closure_event = mozilla::MakeUnique( port->peer_port_name, port->last_sequence_num_to_receive); } } @@ -1374,7 +1330,7 @@ int Node::ForwardUserMessagesFromProxy(const PortRef& port_ref) { // the message queue's notion of next sequence number. That's useful for the // proxy removal process as we can tell when this port has seen all of the // messages it is expected to see. - std::unique_ptr message; + mozilla::UniquePtr message; { SinglePortLocker locker(&port_ref); locker.port()->message_queue.GetNextMessage(&message, nullptr); @@ -1407,7 +1363,7 @@ void Node::InitiateProxyRemoval(const PortRef& port_ref) { // Eventually, this node will receive ObserveProxyAck (or ObserveClosure if // the peer was closed in the meantime). delegate_->ForwardEvent(peer_node_name, - std::make_unique( + mozilla::MakeUnique( peer_port_name, name_, port_ref.name(), peer_node_name, peer_port_name)); } @@ -1451,11 +1407,11 @@ void Node::DestroyAllPortsWithPeer(const NodeName& node_name, std::vector ports_to_notify; std::vector dead_proxies_to_broadcast; - std::vector> undelivered_messages; + std::vector> undelivered_messages; { PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock ports_lock(ports_lock_); + mozilla::MutexAutoLock ports_lock(ports_lock_); auto node_peer_port_map_iter = peer_port_maps_.find(node_name); if (node_peer_port_map_iter == peer_port_maps_.end()) return; @@ -1506,7 +1462,7 @@ void Node::DestroyAllPortsWithPeer(const NodeName& node_name, // inefficient but rare. if (port->state != Port::kReceiving) { dead_proxies_to_broadcast.push_back(local_port_ref.name()); - std::vector> messages; + std::vector> messages; port->message_queue.TakeAllMessages(&messages); for (auto& message : messages) undelivered_messages.emplace_back(std::move(message)); @@ -1525,7 +1481,7 @@ void Node::DestroyAllPortsWithPeer(const NodeName& node_name, for (const auto& proxy_name : dead_proxies_to_broadcast) { // Broadcast an event signifying that this proxy is no longer functioning. - delegate_->BroadcastEvent(std::make_unique( + delegate_->BroadcastEvent(mozilla::MakeUnique( kInvalidPortName, name_, proxy_name, kInvalidNodeName, kInvalidPortName)); @@ -1549,7 +1505,7 @@ void Node::UpdatePortPeerAddress(const PortName& local_port_name, Port* local_port, const NodeName& new_peer_node, const PortName& new_peer_port) { - ports_lock_.AssertAcquired(); + ports_lock_.AssertCurrentThreadOwns(); local_port->AssertLockAcquired(); RemoveFromPeerPortMap(local_port_name, local_port); @@ -1557,8 +1513,7 @@ void Node::UpdatePortPeerAddress(const PortName& local_port_name, local_port->peer_port_name = new_peer_port; if (new_peer_port != kInvalidPortName) { peer_port_maps_[new_peer_node][new_peer_port].emplace( - local_port_name, - PortRef(local_port_name, base::WrapRefCounted(local_port))); + local_port_name, PortRef(local_port_name, RefPtr{local_port})); } } @@ -1581,7 +1536,7 @@ void Node::RemoveFromPeerPortMap(const PortName& local_port_name, void Node::SwapPortPeers(const PortName& port0_name, Port* port0, const PortName& port1_name, Port* port1) { - ports_lock_.AssertAcquired(); + ports_lock_.AssertCurrentThreadOwns(); port0->AssertLockAcquired(); port1->AssertLockAcquired(); @@ -1591,10 +1546,8 @@ void Node::SwapPortPeers(const PortName& port0_name, Port* port0, peer_port_maps_[port1->peer_node_name][port1->peer_port_name]; peer0_ports.erase(port0_name); peer1_ports.erase(port1_name); - peer0_ports.emplace(port1_name, - PortRef(port1_name, base::WrapRefCounted(port1))); - peer1_ports.emplace(port0_name, - PortRef(port0_name, base::WrapRefCounted(port0))); + peer0_ports.emplace(port1_name, PortRef(port1_name, RefPtr{port1})); + peer1_ports.emplace(port0_name, PortRef(port0_name, RefPtr{port0})); std::swap(port0->peer_node_name, port1->peer_node_name); std::swap(port0->peer_port_name, port1->peer_port_name); @@ -1611,7 +1564,7 @@ void Node::MaybeResendAckRequest(const PortRef& port_ref) { if (!port->sequence_num_acknowledge_interval) return; peer_node_name = port->peer_node_name; - ack_request_event = std::make_unique( + ack_request_event = mozilla::MakeUnique( port->peer_port_name, port->last_sequence_num_acknowledged + port->sequence_num_acknowledge_interval); } @@ -1630,7 +1583,7 @@ void Node::MaybeForwardAckRequest(const PortRef& port_ref) { if (!port->sequence_num_to_acknowledge) return; peer_node_name = port->peer_node_name; - ack_request_event = std::make_unique( + ack_request_event = mozilla::MakeUnique( port->peer_port_name, port->sequence_num_to_acknowledge); port->sequence_num_to_acknowledge = 0; @@ -1652,7 +1605,7 @@ void Node::MaybeResendAck(const PortRef& port_ref) { if (!port->sequence_num_to_acknowledge || !last_sequence_num_read) return; peer_node_name = port->peer_node_name; - ack_event = std::make_unique( + ack_event = mozilla::MakeUnique( port->peer_port_name, last_sequence_num_read); } @@ -1666,10 +1619,10 @@ Node::DelegateHolder::DelegateHolder(Node* node, NodeDelegate* delegate) Node::DelegateHolder::~DelegateHolder() = default; -#if DCHECK_IS_ON() +#ifdef DEBUG void Node::DelegateHolder::EnsureSafeDelegateAccess() const { PortLocker::AssertNoPortsLockedOnCurrentThread(); - base::AutoLock lock(node_->ports_lock_); + mozilla::MutexAutoLock lock(node_->ports_lock_); } #endif diff --git a/ipc/chromium/src/mojo/core/ports/node.h b/ipc/chromium/src/mojo/core/ports/node.h index c95ccf3224a1..d31b6dfba127 100644 --- a/ipc/chromium/src/mojo/core/ports/node.h +++ b/ipc/chromium/src/mojo/core/ports/node.h @@ -11,16 +11,13 @@ #include #include -#include "base/component_export.h" -#include "base/containers/flat_map.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" #include "mojo/core/ports/event.h" #include "mojo/core/ports/name.h" #include "mojo/core/ports/port.h" #include "mojo/core/ports/port_ref.h" #include "mojo/core/ports/user_data.h" +#include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" namespace mojo { namespace core { @@ -66,7 +63,7 @@ class NodeDelegate; // by Nodes to coordinate Port behavior and lifetime within and across Nodes. // See Event documentation for description of different types of events used by // a Node to coordinate behavior. -class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { +class Node { public: enum class ShutdownPolicy { DONT_ALLOW_LOCAL_PORTS, @@ -77,6 +74,9 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { Node(const NodeName& name, NodeDelegate* delegate); ~Node(); + Node(const Node&) = delete; + void operator=(const Node&) = delete; + // Returns true iff there are no open ports referring to another node or ports // in the process of being transferred from this node to another. If this // returns false, then to ensure clean shutdown, it is necessary to keep the @@ -108,8 +108,8 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { int CreatePortPair(PortRef* port0_ref, PortRef* port1_ref); // User data associated with the port. - int SetUserData(const PortRef& port_ref, scoped_refptr user_data); - int GetUserData(const PortRef& port_ref, scoped_refptr* user_data); + int SetUserData(const PortRef& port_ref, RefPtr user_data); + int GetUserData(const PortRef& port_ref, RefPtr* user_data); // Prevents further messages from being sent from this port or delivered to // this port. The port is removed, and the port's peer is notified of the @@ -131,14 +131,14 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { // available. Ownership of |filter| is not taken, and it must outlive the // extent of this call. int GetMessage(const PortRef& port_ref, - std::unique_ptr* message, + mozilla::UniquePtr* message, MessageFilter* filter); // Sends a message from the specified port to its peer. Note that the message // notification may arrive synchronously (via PortStatusChanged() on the // delegate) if the peer is local to this Node. int SendUserMessage(const PortRef& port_ref, - std::unique_ptr message); + mozilla::UniquePtr message); // Makes the port send acknowledge requests to its conjugate to acknowledge // at least every |sequence_number_acknowledge_interval| messages as they're @@ -184,13 +184,16 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { DelegateHolder(Node* node, NodeDelegate* delegate); ~DelegateHolder(); + DelegateHolder(const DelegateHolder&) = delete; + void operator=(const DelegateHolder&) = delete; + NodeDelegate* operator->() const { EnsureSafeDelegateAccess(); return delegate_; } private: -#if DCHECK_IS_ON() +#ifdef DEBUG void EnsureSafeDelegateAccess() const; #else void EnsureSafeDelegateAccess() const {} @@ -198,25 +201,23 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { Node* const node_; NodeDelegate* const delegate_; - - DISALLOW_COPY_AND_ASSIGN(DelegateHolder); }; - int OnUserMessage(std::unique_ptr message); - int OnPortAccepted(std::unique_ptr event); - int OnObserveProxy(std::unique_ptr event); - int OnObserveProxyAck(std::unique_ptr event); - int OnObserveClosure(std::unique_ptr event); - int OnMergePort(std::unique_ptr event); + int OnUserMessage(mozilla::UniquePtr message); + int OnPortAccepted(mozilla::UniquePtr event); + int OnObserveProxy(mozilla::UniquePtr event); + int OnObserveProxyAck(mozilla::UniquePtr event); + int OnObserveClosure(mozilla::UniquePtr event); + int OnMergePort(mozilla::UniquePtr event); int OnUserMessageReadAckRequest( - std::unique_ptr event); - int OnUserMessageReadAck(std::unique_ptr event); + mozilla::UniquePtr event); + int OnUserMessageReadAck(mozilla::UniquePtr event); - int AddPortWithName(const PortName& port_name, scoped_refptr port); + int AddPortWithName(const PortName& port_name, RefPtr port); void ErasePort(const PortName& port_name); int SendUserMessageInternal(const PortRef& port_ref, - std::unique_ptr* message); + mozilla::UniquePtr* message); int MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref, bool allow_close_on_bad_state); void ConvertToProxy(Port* port, const NodeName& to_node_name, @@ -286,24 +287,27 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { // Because UserMessage events may execute arbitrary user code during // destruction, it is also important to ensure that such events are never // destroyed while this (or any individual Port) lock is held. - base::Lock ports_lock_; - std::unordered_map> ports_; + mozilla::Mutex ports_lock_{"Ports Lock"}; + std::unordered_map> ports_; // Maps a peer port name to a list of PortRefs for all local ports which have // the port name key designated as their peer port. The set of local ports // which have the same peer port is expected to always be relatively small and // usually 1. Hence we just use a flat_map of local PortRefs keyed on each // local port's name. + // + // FIXME(nika): We don't have `base::flat_map` or a super equivalent type with + // the same API, so just use a nested `std::unordered_map` for now. We should + // probably change all of this to instead use our types eventually. using PeerPortMap = - std::unordered_map>; + std::unordered_map>; // A reverse mapping which can be used to find all local ports that reference // a given peer node or a local port that references a specific given peer // port on a peer node. The key to this map is the corresponding peer node // name. std::unordered_map peer_port_maps_; - - DISALLOW_COPY_AND_ASSIGN(Node); }; } // namespace ports diff --git a/ipc/chromium/src/mojo/core/ports/port.h b/ipc/chromium/src/mojo/core/ports/port.h index cd798df0bd28..b74c23f00b6a 100644 --- a/ipc/chromium/src/mojo/core/ports/port.h +++ b/ipc/chromium/src/mojo/core/ports/port.h @@ -10,12 +10,12 @@ #include #include -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" #include "mojo/core/ports/event.h" #include "mojo/core/ports/message_queue.h" #include "mojo/core/ports/user_data.h" +#include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" namespace mojo { namespace core { @@ -61,7 +61,9 @@ class PortLocker; // which is only possible using a PortLocker. PortLocker ensures that // overlapping Port lock acquisitions on a single thread are always acquired in // a globally consistent order. -class Port : public base::RefCountedThreadSafe { +class Port { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Port) + public: // The state of a given Port. A Port may only exist in one of these states at // any given time. @@ -149,12 +151,12 @@ class Port : public base::RefCountedThreadSafe { // In some edge cases, a Node may need to remember to route a single special // event upon destruction of this (proxying) Port. That event is stashed here // in the interim. - std::unique_ptr> send_on_proxy_removal; + mozilla::UniquePtr> send_on_proxy_removal; // Arbitrary user data attached to the Port. In practice, Mojo uses this to // stash an observer interface which can be notified about various Port state // changes. - scoped_refptr user_data; + RefPtr user_data; // Indicates that this (proxying) Port has received acknowledgement that no // new user messages will be routed to it. If |true|, the proxy will be @@ -176,21 +178,17 @@ class Port : public base::RefCountedThreadSafe { Port(uint64_t next_sequence_num_to_send, uint64_t next_sequence_num_to_receive); - void AssertLockAcquired() { -#if DCHECK_IS_ON() - lock_.AssertAcquired(); -#endif - } + Port(const Port&) = delete; + void operator=(const Port&) = delete; + + void AssertLockAcquired() { lock_.AssertCurrentThreadOwns(); } private: - friend class base::RefCountedThreadSafe; friend class PortLocker; ~Port(); - base::Lock lock_; - - DISALLOW_COPY_AND_ASSIGN(Port); + mozilla::Mutex lock_{"Port State"}; }; } // namespace ports diff --git a/ipc/chromium/src/mojo/core/ports/port_locker.cc b/ipc/chromium/src/mojo/core/ports/port_locker.cc index 4bcc4054cf80..8d49298b3360 100644 --- a/ipc/chromium/src/mojo/core/ports/port_locker.cc +++ b/ipc/chromium/src/mojo/core/ports/port_locker.cc @@ -8,8 +8,8 @@ #include "mojo/core/ports/port.h" -#if DCHECK_IS_ON() -# include "base/threading/thread_local.h" +#ifdef DEBUG +# include "base/thread_local.h" #endif namespace mojo { @@ -18,7 +18,7 @@ namespace ports { namespace { -#if DCHECK_IS_ON() +#ifdef DEBUG void UpdateTLS(PortLocker* old_locker, PortLocker* new_locker) { // Sanity check when DCHECK is on to make sure there is only ever one // PortLocker extant on the current thread. @@ -32,7 +32,7 @@ void UpdateTLS(PortLocker* old_locker, PortLocker* new_locker) { PortLocker::PortLocker(const PortRef** port_refs, size_t num_ports) : port_refs_(port_refs), num_ports_(num_ports) { -#if DCHECK_IS_ON() +#ifdef DEBUG UpdateTLS(nullptr, this); #endif @@ -43,20 +43,19 @@ PortLocker::PortLocker(const PortRef** port_refs, size_t num_ports) for (size_t i = 0; i < num_ports_; ++i) { // TODO(crbug.com/725605): Remove this CHECK. CHECK(port_refs_[i]->port()); - port_refs_[i]->port()->lock_.Acquire(); + port_refs_[i]->port()->lock_.Lock(); } } PortLocker::~PortLocker() { - for (size_t i = 0; i < num_ports_; ++i) - port_refs_[i]->port()->lock_.Release(); + for (size_t i = 0; i < num_ports_; ++i) port_refs_[i]->port()->lock_.Unlock(); -#if DCHECK_IS_ON() +#ifdef DEBUG UpdateTLS(this, nullptr); #endif } -#if DCHECK_IS_ON() +#ifdef DEBUG // static void PortLocker::AssertNoPortsLockedOnCurrentThread() { // Forces a DCHECK if the TLS PortLocker is anything other than null. diff --git a/ipc/chromium/src/mojo/core/ports/port_locker.h b/ipc/chromium/src/mojo/core/ports/port_locker.h index 5a0ba9e304f2..38be3c726bab 100644 --- a/ipc/chromium/src/mojo/core/ports/port_locker.h +++ b/ipc/chromium/src/mojo/core/ports/port_locker.h @@ -7,7 +7,7 @@ #include -#include "base/macros.h" +#include "base/logging.h" #include "mojo/core/ports/port_ref.h" namespace mojo { @@ -31,14 +31,17 @@ class PortLocker { PortLocker(const PortRef** port_refs, size_t num_ports); ~PortLocker(); + PortLocker(const PortLocker&) = delete; + void operator=(const PortLocker&) = delete; + // Provides safe access to a PortRef's Port. Note that in release builds this // doesn't do anything other than pass through to the private accessor on // |port_ref|, but it does force callers to go through a PortLocker to get to // the state, thus minimizing the likelihood that they'll go and do something // stupid. Port* GetPort(const PortRef& port_ref) const { -#if DCHECK_IS_ON() - // Sanity check when DCHECK is on to ensure this is actually a port whose +#ifdef DEBUG + // Sanity check when DEBUG is on to ensure this is actually a port whose // lock is held by this PortLocker. bool is_port_locked = false; for (size_t i = 0; i < num_ports_ && !is_port_locked; ++i) @@ -50,7 +53,7 @@ class PortLocker { // A helper which can be used to verify that no Port locks are held on the // current thread. In non-DCHECK builds this is a no-op. -#if DCHECK_IS_ON() +#ifdef DEBUG static void AssertNoPortsLockedOnCurrentThread(); #else static void AssertNoPortsLockedOnCurrentThread() {} @@ -59,8 +62,6 @@ class PortLocker { private: const PortRef** const port_refs_; const size_t num_ports_; - - DISALLOW_COPY_AND_ASSIGN(PortLocker); }; // Convenience wrapper for a PortLocker that locks a single port. @@ -69,13 +70,14 @@ class SinglePortLocker { explicit SinglePortLocker(const PortRef* port_ref); ~SinglePortLocker(); + SinglePortLocker(const SinglePortLocker&) = delete; + void operator=(const SinglePortLocker&) = delete; + Port* port() const { return locker_.GetPort(*port_ref_); } private: const PortRef* port_ref_; PortLocker locker_; - - DISALLOW_COPY_AND_ASSIGN(SinglePortLocker); }; } // namespace ports diff --git a/ipc/chromium/src/mojo/core/ports/port_ref.cc b/ipc/chromium/src/mojo/core/ports/port_ref.cc index 7cbc53674c7d..b9267f8a6a1f 100644 --- a/ipc/chromium/src/mojo/core/ports/port_ref.cc +++ b/ipc/chromium/src/mojo/core/ports/port_ref.cc @@ -14,7 +14,7 @@ PortRef::~PortRef() = default; PortRef::PortRef() = default; -PortRef::PortRef(const PortName& name, scoped_refptr port) +PortRef::PortRef(const PortName& name, RefPtr port) : name_(name), port_(std::move(port)) {} PortRef::PortRef(const PortRef& other) = default; diff --git a/ipc/chromium/src/mojo/core/ports/port_ref.h b/ipc/chromium/src/mojo/core/ports/port_ref.h index afa75e54c179..0ff0d32fc78c 100644 --- a/ipc/chromium/src/mojo/core/ports/port_ref.h +++ b/ipc/chromium/src/mojo/core/ports/port_ref.h @@ -5,9 +5,8 @@ #ifndef MOJO_CORE_PORTS_PORT_REF_H_ #define MOJO_CORE_PORTS_PORT_REF_H_ -#include "base/component_export.h" -#include "base/memory/ref_counted.h" #include "mojo/core/ports/name.h" +#include "mozilla/RefPtr.h" namespace mojo { namespace core { @@ -16,11 +15,11 @@ namespace ports { class Port; class PortLocker; -class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortRef { +class PortRef { public: ~PortRef(); PortRef(); - PortRef(const PortName& name, scoped_refptr port); + PortRef(const PortName& name, RefPtr port); PortRef(const PortRef& other); PortRef(PortRef&& other); @@ -38,7 +37,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortRef { Port* port() const { return port_.get(); } PortName name_; - scoped_refptr port_; + RefPtr port_; }; } // namespace ports diff --git a/ipc/chromium/src/mojo/core/ports/user_data.h b/ipc/chromium/src/mojo/core/ports/user_data.h index 2d2b25fc01b2..f3d568c259df 100644 --- a/ipc/chromium/src/mojo/core/ports/user_data.h +++ b/ipc/chromium/src/mojo/core/ports/user_data.h @@ -5,16 +5,16 @@ #ifndef MOJO_CORE_PORTS_USER_DATA_H_ #define MOJO_CORE_PORTS_USER_DATA_H_ -#include "base/memory/ref_counted.h" +#include "nsISupportsImpl.h" namespace mojo { namespace core { namespace ports { -class UserData : public base::RefCountedThreadSafe { - protected: - friend class base::RefCountedThreadSafe; +class UserData { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UserData); + protected: virtual ~UserData() = default; }; diff --git a/ipc/chromium/src/mojo/core/ports/user_message.h b/ipc/chromium/src/mojo/core/ports/user_message.h index e30e316a08b0..689d9691f848 100644 --- a/ipc/chromium/src/mojo/core/ports/user_message.h +++ b/ipc/chromium/src/mojo/core/ports/user_message.h @@ -7,9 +7,6 @@ #include -#include "base/component_export.h" -#include "base/macros.h" - namespace mojo { namespace core { namespace ports { @@ -24,13 +21,16 @@ namespace ports { // |kUserMessageTypeInfo| and pass its address down to the UserMessage // constructor. The type of a UserMessage can then be dynamically inspected by // comparing |type_info()| to any subclass's |&kUserMessageTypeInfo|. -class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessage { +class UserMessage { public: struct TypeInfo {}; explicit UserMessage(const TypeInfo* type_info); virtual ~UserMessage(); + UserMessage(const UserMessage&) = delete; + void operator=(const UserMessage&) = delete; + const TypeInfo* type_info() const { return type_info_; } // Invoked immediately before the system asks the embedder to forward this @@ -47,8 +47,6 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessage { private: const TypeInfo* const type_info_; - - DISALLOW_COPY_AND_ASSIGN(UserMessage); }; } // namespace ports