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
This commit is contained in:
Nika Layzell 2021-06-22 18:17:18 +00:00
Родитель d1f7ecf8e1
Коммит 03f4afa8fb
19 изменённых файлов: 275 добавлений и 359 удалений

Просмотреть файл

@ -29,6 +29,14 @@ UNIFIED_SOURCES += [
"src/chrome/common/chrome_switches.cc", "src/chrome/common/chrome_switches.cc",
"src/chrome/common/ipc_channel_utils.cc", "src/chrome/common/ipc_channel_utils.cc",
"src/chrome/common/ipc_message.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: if os_win:

Просмотреть файл

@ -23,7 +23,6 @@
namespace base { namespace base {
#define DVLOG(x) CHROMIUM_LOG(ERROR)
#define CHECK_GT DCHECK_GT #define CHECK_GT DCHECK_GT
#define CHECK_LT DCHECK_LT #define CHECK_LT DCHECK_LT

Просмотреть файл

@ -106,6 +106,8 @@ const mozilla::EmptyLog& operator<<(const mozilla::EmptyLog& log, const T&) {
while (false && (condition)) mozilla::EmptyLog() while (false && (condition)) mozilla::EmptyLog()
#endif #endif
#define DVLOG(level) DLOG(INFO)
#undef LOG_ASSERT #undef LOG_ASSERT
#define LOG_ASSERT(cond) CHECK(0) #define LOG_ASSERT(cond) CHECK(0)
#define DLOG_ASSERT(cond) DCHECK(0) #define DLOG_ASSERT(cond) DCHECK(0)

Просмотреть файл

@ -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",
]
}

Просмотреть файл

@ -8,8 +8,9 @@
#include <string.h> #include <string.h>
#include "base/logging.h" #include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "mojo/core/ports/user_message.h" #include "mojo/core/ports/user_message.h"
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
@ -156,7 +157,7 @@ UserMessageEvent::UserMessageEvent(size_t num_ports)
ReservePorts(num_ports); ReservePorts(num_ports);
} }
void UserMessageEvent::AttachMessage(std::unique_ptr<UserMessage> message) { void UserMessageEvent::AttachMessage(mozilla::UniquePtr<UserMessage> message) {
DCHECK(!message_); DCHECK(!message_);
message_ = std::move(message); message_ = std::move(message);
} }
@ -178,17 +179,16 @@ ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name,
if (num_bytes < sizeof(UserMessageEventData)) return nullptr; if (num_bytes < sizeof(UserMessageEventData)) return nullptr;
const auto* data = static_cast<const UserMessageEventData*>(buffer); const auto* data = static_cast<const UserMessageEventData*>(buffer);
base::CheckedNumeric<size_t> port_data_size = data->num_ports; mozilla::CheckedInt<size_t> port_data_size = data->num_ports;
port_data_size *= sizeof(PortDescriptor) + sizeof(PortName); port_data_size *= sizeof(PortDescriptor) + sizeof(PortName);
if (!port_data_size.IsValid()) return nullptr; if (!port_data_size.isValid()) return nullptr;
base::CheckedNumeric<size_t> total_size = port_data_size.ValueOrDie(); mozilla::CheckedInt<size_t> total_size = port_data_size.value();
total_size += sizeof(UserMessageEventData); total_size += sizeof(UserMessageEventData);
if (!total_size.IsValid() || num_bytes < total_size.ValueOrDie()) if (!total_size.isValid() || num_bytes < total_size.value()) return nullptr;
return nullptr;
auto event = 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); event->ReservePorts(data->num_ports);
const auto* in_descriptors = const auto* in_descriptors =
reinterpret_cast<const PortDescriptor*>(data + 1); reinterpret_cast<const PortDescriptor*>(data + 1);
@ -198,7 +198,7 @@ ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name,
const auto* in_names = const auto* in_names =
reinterpret_cast<const PortName*>(in_descriptors + data->num_ports); reinterpret_cast<const PortName*>(in_descriptors + data->num_ports);
std::copy(in_names, in_names + data->num_ports, event->ports()); std::copy(in_names, in_names + data->num_ports, event->ports());
return std::move(event); return event;
} }
UserMessageEvent::UserMessageEvent(const PortName& port_name, UserMessageEvent::UserMessageEvent(const PortName& port_name,
@ -212,19 +212,22 @@ size_t UserMessageEvent::GetSizeIfSerialized() const {
size_t UserMessageEvent::GetSerializedDataSize() const { size_t UserMessageEvent::GetSerializedDataSize() const {
DCHECK_EQ(ports_.size(), port_descriptors_.size()); DCHECK_EQ(ports_.size(), port_descriptors_.size());
base::CheckedNumeric<size_t> size = sizeof(UserMessageEventData); mozilla::CheckedInt<size_t> size = sizeof(UserMessageEventData);
base::CheckedNumeric<size_t> ports_size = mozilla::CheckedInt<size_t> ports_size =
sizeof(PortDescriptor) + sizeof(PortName); sizeof(PortDescriptor) + sizeof(PortName);
ports_size *= ports_.size(); ports_size *= ports_.size();
return (size + ports_size.ValueOrDie()).ValueOrDie(); mozilla::CheckedInt<size_t> combined = size + ports_size;
MOZ_RELEASE_ASSERT(combined.isValid());
return combined.value();
} }
void UserMessageEvent::SerializeData(void* buffer) const { void UserMessageEvent::SerializeData(void* buffer) const {
DCHECK_EQ(ports_.size(), port_descriptors_.size()); DCHECK_EQ(ports_.size(), port_descriptors_.size());
auto* data = static_cast<UserMessageEventData*>(buffer); auto* data = static_cast<UserMessageEventData*>(buffer);
data->sequence_num = sequence_num_; data->sequence_num = sequence_num_;
DCHECK(base::IsValueInRangeForNumericType<uint32_t>(ports_.size())); mozilla::CheckedInt<uint32_t> num_ports{ports_.size()};
data->num_ports = static_cast<uint32_t>(ports_.size()); DCHECK(num_ports.isValid());
data->num_ports = num_ports.value();
data->padding = 0; data->padding = 0;
auto* ports_data = reinterpret_cast<PortDescriptor*>(data + 1); auto* ports_data = reinterpret_cast<PortDescriptor*>(data + 1);
@ -244,7 +247,7 @@ PortAcceptedEvent::~PortAcceptedEvent() = default;
ScopedEvent PortAcceptedEvent::Deserialize(const PortName& port_name, ScopedEvent PortAcceptedEvent::Deserialize(const PortName& port_name,
const void* buffer, const void* buffer,
size_t num_bytes) { size_t num_bytes) {
return std::make_unique<PortAcceptedEvent>(port_name); return mozilla::MakeUnique<PortAcceptedEvent>(port_name);
} }
size_t PortAcceptedEvent::GetSerializedDataSize() const { return 0; } 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; if (num_bytes < sizeof(ObserveProxyEventData)) return nullptr;
const auto* data = static_cast<const ObserveProxyEventData*>(buffer); const auto* data = static_cast<const ObserveProxyEventData*>(buffer);
return std::make_unique<ObserveProxyEvent>( return mozilla::MakeUnique<ObserveProxyEvent>(
port_name, data->proxy_node_name, data->proxy_port_name, port_name, data->proxy_node_name, data->proxy_port_name,
data->proxy_target_node_name, data->proxy_target_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 { ScopedEvent ObserveProxyEvent::Clone() const {
return std::make_unique<ObserveProxyEvent>( return mozilla::MakeUnique<ObserveProxyEvent>(
port_name(), proxy_node_name_, proxy_port_name_, proxy_target_node_name_, port_name(), proxy_node_name_, proxy_port_name_, proxy_target_node_name_,
proxy_target_port_name_); proxy_target_port_name_);
} }
@ -308,8 +311,8 @@ ScopedEvent ObserveProxyAckEvent::Deserialize(const PortName& port_name,
if (num_bytes < sizeof(ObserveProxyAckEventData)) return nullptr; if (num_bytes < sizeof(ObserveProxyAckEventData)) return nullptr;
const auto* data = static_cast<const ObserveProxyAckEventData*>(buffer); const auto* data = static_cast<const ObserveProxyAckEventData*>(buffer);
return std::make_unique<ObserveProxyAckEvent>(port_name, return mozilla::MakeUnique<ObserveProxyAckEvent>(port_name,
data->last_sequence_num); data->last_sequence_num);
} }
size_t ObserveProxyAckEvent::GetSerializedDataSize() const { size_t ObserveProxyAckEvent::GetSerializedDataSize() const {
@ -322,8 +325,8 @@ void ObserveProxyAckEvent::SerializeData(void* buffer) const {
} }
ScopedEvent ObserveProxyAckEvent::Clone() const { ScopedEvent ObserveProxyAckEvent::Clone() const {
return std::make_unique<ObserveProxyAckEvent>(port_name(), return mozilla::MakeUnique<ObserveProxyAckEvent>(port_name(),
last_sequence_num_); last_sequence_num_);
} }
ObserveClosureEvent::ObserveClosureEvent(const PortName& port_name, ObserveClosureEvent::ObserveClosureEvent(const PortName& port_name,
@ -340,8 +343,8 @@ ScopedEvent ObserveClosureEvent::Deserialize(const PortName& port_name,
if (num_bytes < sizeof(ObserveClosureEventData)) return nullptr; if (num_bytes < sizeof(ObserveClosureEventData)) return nullptr;
const auto* data = static_cast<const ObserveClosureEventData*>(buffer); const auto* data = static_cast<const ObserveClosureEventData*>(buffer);
return std::make_unique<ObserveClosureEvent>(port_name, return mozilla::MakeUnique<ObserveClosureEvent>(port_name,
data->last_sequence_num); data->last_sequence_num);
} }
size_t ObserveClosureEvent::GetSerializedDataSize() const { size_t ObserveClosureEvent::GetSerializedDataSize() const {
@ -354,7 +357,8 @@ void ObserveClosureEvent::SerializeData(void* buffer) const {
} }
ScopedEvent ObserveClosureEvent::Clone() const { ScopedEvent ObserveClosureEvent::Clone() const {
return std::make_unique<ObserveClosureEvent>(port_name(), last_sequence_num_); return mozilla::MakeUnique<ObserveClosureEvent>(port_name(),
last_sequence_num_);
} }
MergePortEvent::MergePortEvent(const PortName& port_name, MergePortEvent::MergePortEvent(const PortName& port_name,
@ -372,8 +376,8 @@ ScopedEvent MergePortEvent::Deserialize(const PortName& port_name,
if (num_bytes < sizeof(MergePortEventData)) return nullptr; if (num_bytes < sizeof(MergePortEventData)) return nullptr;
const auto* data = static_cast<const MergePortEventData*>(buffer); const auto* data = static_cast<const MergePortEventData*>(buffer);
return std::make_unique<MergePortEvent>(port_name, data->new_port_name, return mozilla::MakeUnique<MergePortEvent>(port_name, data->new_port_name,
data->new_port_descriptor); data->new_port_descriptor);
} }
size_t MergePortEvent::GetSerializedDataSize() const { size_t MergePortEvent::GetSerializedDataSize() const {
@ -400,7 +404,7 @@ ScopedEvent UserMessageReadAckRequestEvent::Deserialize(
const auto* data = const auto* data =
static_cast<const UserMessageReadAckRequestEventData*>(buffer); static_cast<const UserMessageReadAckRequestEventData*>(buffer);
return std::make_unique<UserMessageReadAckRequestEvent>( return mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
port_name, data->sequence_num_to_acknowledge); 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; if (num_bytes < sizeof(UserMessageReadAckEventData)) return nullptr;
const auto* data = static_cast<const UserMessageReadAckEventData*>(buffer); const auto* data = static_cast<const UserMessageReadAckEventData*>(buffer);
return std::make_unique<UserMessageReadAckEvent>( return mozilla::MakeUnique<UserMessageReadAckEvent>(
port_name, data->sequence_num_acknowledged); port_name, data->sequence_num_acknowledged);
} }

Просмотреть файл

@ -7,11 +7,9 @@
#include <stdint.h> #include <stdint.h>
#include <memory>
#include <vector> #include <vector>
#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/name.h"
#include "mojo/core/ports/user_message.h" #include "mojo/core/ports/user_message.h"
@ -21,11 +19,11 @@ namespace ports {
class Event; class Event;
using ScopedEvent = std::unique_ptr<Event>; using ScopedEvent = mozilla::UniquePtr<Event>;
// A Event is the fundamental unit of operation and communication within and // A Event is the fundamental unit of operation and communication within and
// between Nodes. // between Nodes.
class COMPONENT_EXPORT(MOJO_CORE_PORTS) Event { class Event {
public: public:
enum Type : uint32_t { enum Type : uint32_t {
// A user message event contains arbitrary user-specified payload data // 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); static ScopedEvent Deserialize(const void* buffer, size_t num_bytes);
template <typename T> template <typename T>
static std::unique_ptr<T> Cast(ScopedEvent* event) { static mozilla::UniquePtr<T> Cast(ScopedEvent* event) {
return base::WrapUnique(static_cast<T*>(event->release())); return mozilla::WrapUnique(static_cast<T*>(event->release()));
} }
Type type() const { return type_; } Type type() const { return type_; }
@ -110,13 +108,13 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Event {
DISALLOW_COPY_AND_ASSIGN(Event); DISALLOW_COPY_AND_ASSIGN(Event);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event { class UserMessageEvent : public Event {
public: public:
explicit UserMessageEvent(size_t num_ports); explicit UserMessageEvent(size_t num_ports);
~UserMessageEvent() override; ~UserMessageEvent() override;
bool HasMessage() const { return !!message_; } bool HasMessage() const { return !!message_; }
void AttachMessage(std::unique_ptr<UserMessage> message); void AttachMessage(mozilla::UniquePtr<UserMessage> message);
template <typename T> template <typename T>
T* GetMessage() { T* GetMessage() {
@ -156,12 +154,12 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event {
uint64_t sequence_num_ = 0; uint64_t sequence_num_ = 0;
std::vector<PortDescriptor> port_descriptors_; std::vector<PortDescriptor> port_descriptors_;
std::vector<PortName> ports_; std::vector<PortName> ports_;
std::unique_ptr<UserMessage> message_; mozilla::UniquePtr<UserMessage> message_;
DISALLOW_COPY_AND_ASSIGN(UserMessageEvent); DISALLOW_COPY_AND_ASSIGN(UserMessageEvent);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortAcceptedEvent : public Event { class PortAcceptedEvent : public Event {
public: public:
explicit PortAcceptedEvent(const PortName& port_name); explicit PortAcceptedEvent(const PortName& port_name);
~PortAcceptedEvent() override; ~PortAcceptedEvent() override;
@ -176,7 +174,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortAcceptedEvent : public Event {
DISALLOW_COPY_AND_ASSIGN(PortAcceptedEvent); DISALLOW_COPY_AND_ASSIGN(PortAcceptedEvent);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyEvent : public Event { class ObserveProxyEvent : public Event {
public: public:
ObserveProxyEvent(const PortName& port_name, const NodeName& proxy_node_name, ObserveProxyEvent(const PortName& port_name, const NodeName& proxy_node_name,
const PortName& proxy_port_name, const PortName& proxy_port_name,
@ -209,7 +207,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyEvent : public Event {
DISALLOW_COPY_AND_ASSIGN(ObserveProxyEvent); DISALLOW_COPY_AND_ASSIGN(ObserveProxyEvent);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyAckEvent : public Event { class ObserveProxyAckEvent : public Event {
public: public:
ObserveProxyAckEvent(const PortName& port_name, uint64_t last_sequence_num); ObserveProxyAckEvent(const PortName& port_name, uint64_t last_sequence_num);
~ObserveProxyAckEvent() override; ~ObserveProxyAckEvent() override;
@ -229,7 +227,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyAckEvent : public Event {
DISALLOW_COPY_AND_ASSIGN(ObserveProxyAckEvent); DISALLOW_COPY_AND_ASSIGN(ObserveProxyAckEvent);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveClosureEvent : public Event { class ObserveClosureEvent : public Event {
public: public:
ObserveClosureEvent(const PortName& port_name, uint64_t last_sequence_num); ObserveClosureEvent(const PortName& port_name, uint64_t last_sequence_num);
~ObserveClosureEvent() override; ~ObserveClosureEvent() override;
@ -252,7 +250,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveClosureEvent : public Event {
DISALLOW_COPY_AND_ASSIGN(ObserveClosureEvent); DISALLOW_COPY_AND_ASSIGN(ObserveClosureEvent);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) MergePortEvent : public Event { class MergePortEvent : public Event {
public: public:
MergePortEvent(const PortName& port_name, const PortName& new_port_name, MergePortEvent(const PortName& port_name, const PortName& new_port_name,
const PortDescriptor& new_port_descriptor); const PortDescriptor& new_port_descriptor);
@ -276,8 +274,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) MergePortEvent : public Event {
DISALLOW_COPY_AND_ASSIGN(MergePortEvent); DISALLOW_COPY_AND_ASSIGN(MergePortEvent);
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckRequestEvent class UserMessageReadAckRequestEvent : public Event {
: public Event {
public: public:
UserMessageReadAckRequestEvent(const PortName& port_name, UserMessageReadAckRequestEvent(const PortName& port_name,
uint64_t sequence_num_to_acknowledge); uint64_t sequence_num_to_acknowledge);
@ -297,7 +294,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckRequestEvent
uint64_t sequence_num_to_acknowledge_; uint64_t sequence_num_to_acknowledge_;
}; };
class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckEvent : public Event { class UserMessageReadAckEvent : public Event {
public: public:
UserMessageReadAckEvent(const PortName& port_name, UserMessageReadAckEvent(const PortName& port_name,
uint64_t sequence_num_acknowledged); uint64_t sequence_num_acknowledged);

Просмотреть файл

@ -9,14 +9,15 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "mojo/core/ports/message_filter.h" #include "mojo/core/ports/message_filter.h"
#include "mozilla/Likely.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
namespace ports { namespace ports {
// Used by std::{push,pop}_heap functions // Used by std::{push,pop}_heap functions
inline bool operator<(const std::unique_ptr<UserMessageEvent>& a, inline bool operator<(const mozilla::UniquePtr<UserMessageEvent>& a,
const std::unique_ptr<UserMessageEvent>& b) { const mozilla::UniquePtr<UserMessageEvent>& b) {
return a->sequence_num() > b->sequence_num(); return a->sequence_num() > b->sequence_num();
} }
@ -29,11 +30,15 @@ MessageQueue::MessageQueue(uint64_t next_sequence_num)
} }
MessageQueue::~MessageQueue() { MessageQueue::~MessageQueue() {
#if DCHECK_IS_ON() #ifdef DEBUG
size_t num_leaked_ports = 0; size_t num_leaked_ports = 0;
for (const auto& message : heap_) num_leaked_ports += message->num_ports(); for (const auto& message : heap_) {
DVLOG_IF(1, num_leaked_ports > 0) num_leaked_ports += message->num_ports();
<< "Leaking " << num_leaked_ports << " ports in unreceived messages"; }
if (num_leaked_ports > 0) {
DVLOG(1) << "Leaking " << num_leaked_ports
<< " ports in unreceived messages";
}
#endif #endif
} }
@ -41,7 +46,7 @@ bool MessageQueue::HasNextMessage() const {
return !heap_.empty() && heap_[0]->sequence_num() == next_sequence_num_; return !heap_.empty() && heap_[0]->sequence_num() == next_sequence_num_;
} }
void MessageQueue::GetNextMessage(std::unique_ptr<UserMessageEvent>* message, void MessageQueue::GetNextMessage(mozilla::UniquePtr<UserMessageEvent>* message,
MessageFilter* filter) { MessageFilter* filter) {
if (!HasNextMessage() || (filter && !filter->Match(*heap_[0]))) { if (!HasNextMessage() || (filter && !filter->Match(*heap_[0]))) {
message->reset(); message->reset();
@ -58,15 +63,15 @@ void MessageQueue::GetNextMessage(std::unique_ptr<UserMessageEvent>* message,
// here is somewhat arbitrary. // here is somewhat arbitrary.
constexpr size_t kHeapMinimumShrinkSize = 16; constexpr size_t kHeapMinimumShrinkSize = 16;
constexpr size_t kHeapShrinkInterval = 512; constexpr size_t kHeapShrinkInterval = 512;
if (UNLIKELY(heap_.size() > kHeapMinimumShrinkSize && if (MOZ_UNLIKELY(heap_.size() > kHeapMinimumShrinkSize &&
heap_.size() % kHeapShrinkInterval == 0)) { heap_.size() % kHeapShrinkInterval == 0)) {
heap_.shrink_to_fit(); heap_.shrink_to_fit();
} }
next_sequence_num_++; next_sequence_num_++;
} }
void MessageQueue::AcceptMessage(std::unique_ptr<UserMessageEvent> message, void MessageQueue::AcceptMessage(mozilla::UniquePtr<UserMessageEvent> message,
bool* has_next_message) { bool* has_next_message) {
// TODO: Handle sequence number roll-over. // TODO: Handle sequence number roll-over.
@ -82,7 +87,7 @@ void MessageQueue::AcceptMessage(std::unique_ptr<UserMessageEvent> message,
} }
void MessageQueue::TakeAllMessages( void MessageQueue::TakeAllMessages(
std::vector<std::unique_ptr<UserMessageEvent>>* messages) { std::vector<mozilla::UniquePtr<UserMessageEvent>>* messages) {
*messages = std::move(heap_); *messages = std::move(heap_);
total_queued_bytes_ = 0; total_queued_bytes_ = 0;
} }

Просмотреть файл

@ -11,8 +11,6 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "base/component_export.h"
#include "base/macros.h"
#include "mojo/core/ports/event.h" #include "mojo/core/ports/event.h"
namespace mojo { namespace mojo {
@ -28,12 +26,15 @@ class MessageFilter;
// known sequence number and can indicate whether the next sequential message is // known sequence number and can indicate whether the next sequential message is
// available. Thus the queue enforces message ordering for the consumer without // available. Thus the queue enforces message ordering for the consumer without
// enforcing it for the producer (see AcceptMessage() below.) // enforcing it for the producer (see AcceptMessage() below.)
class COMPONENT_EXPORT(MOJO_CORE_PORTS) MessageQueue { class MessageQueue {
public: public:
explicit MessageQueue(); explicit MessageQueue();
explicit MessageQueue(uint64_t next_sequence_num); explicit MessageQueue(uint64_t next_sequence_num);
~MessageQueue(); ~MessageQueue();
MessageQueue(const MessageQueue&) = delete;
void operator=(const MessageQueue&) = delete;
void set_signalable(bool value) { signalable_ = value; } void set_signalable(bool value) { signalable_ = value; }
uint64_t next_sequence_num() const { return next_sequence_num_; } 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 // Gives ownership of the message. If |filter| is non-null, the next message
// will only be retrieved if the filter successfully matches it. // will only be retrieved if the filter successfully matches it.
void GetNextMessage(std::unique_ptr<UserMessageEvent>* message, void GetNextMessage(mozilla::UniquePtr<UserMessageEvent>* message,
MessageFilter* filter); MessageFilter* filter);
// Takes ownership of the message. Note: Messages are ordered, so while we // 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. // until GetNextMessage is called enough times to return a null message.
// In other words, has_next_message acts like an edge trigger. // In other words, has_next_message acts like an edge trigger.
// //
void AcceptMessage(std::unique_ptr<UserMessageEvent> message, void AcceptMessage(mozilla::UniquePtr<UserMessageEvent> message,
bool* has_next_message); bool* has_next_message);
// Takes all messages from this queue. Used to safely destroy queued messages // Takes all messages from this queue. Used to safely destroy queued messages
// without holding any Port lock. // without holding any Port lock.
void TakeAllMessages( void TakeAllMessages(
std::vector<std::unique_ptr<UserMessageEvent>>* messages); std::vector<mozilla::UniquePtr<UserMessageEvent>>* messages);
// The number of messages queued here, regardless of whether the next expected // The number of messages queued here, regardless of whether the next expected
// message has arrived yet. // 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_; } size_t queued_num_bytes() const { return total_queued_bytes_; }
private: private:
std::vector<std::unique_ptr<UserMessageEvent>> heap_; std::vector<mozilla::UniquePtr<UserMessageEvent>> heap_;
uint64_t next_sequence_num_; uint64_t next_sequence_num_;
bool signalable_ = true; bool signalable_ = true;
size_t total_queued_bytes_ = 0; size_t total_queued_bytes_ = 0;
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
}; };
} // namespace ports } // namespace ports

Просмотреть файл

@ -20,6 +20,14 @@ std::ostream& operator<<(std::ostream& stream, const Name& name) {
return stream; 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 ports
} // namespace core } // namespace core
} // namespace mojo } // namespace mojo

Просмотреть файл

@ -10,14 +10,14 @@
#include <ostream> #include <ostream>
#include <tuple> #include <tuple>
#include "base/component_export.h" #include "base/logging.h"
#include "base/hash/hash.h" #include "mozilla/HashFunctions.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
namespace ports { namespace ports {
struct COMPONENT_EXPORT(MOJO_CORE_PORTS) Name { struct Name {
Name(uint64_t v1, uint64_t v2) : v1(v1), v2(v2) {} Name(uint64_t v1, uint64_t v2) : v1(v1), v2(v2) {}
uint64_t v1, 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); 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); 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() : Name(0, 0) {}
PortName(uint64_t v1, uint64_t v2) : Name(v1, v2) {} 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() : Name(0, 0) {}
NodeName(uint64_t v1, uint64_t v2) : Name(v1, v2) {} 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 ports
} // namespace core } // namespace core
@ -56,16 +56,18 @@ extern COMPONENT_EXPORT(MOJO_CORE_PORTS) const NodeName kInvalidNodeName;
namespace std { namespace std {
template <> template <>
struct COMPONENT_EXPORT(MOJO_CORE_PORTS) hash<mojo::core::ports::PortName> { struct hash<mojo::core::ports::PortName> {
std::size_t operator()(const mojo::core::ports::PortName& name) const { 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 <> template <>
struct COMPONENT_EXPORT(MOJO_CORE_PORTS) hash<mojo::core::ports::NodeName> { struct hash<mojo::core::ports::NodeName> {
std::size_t operator()(const mojo::core::ports::NodeName& name) const { 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);
} }
}; };

Просмотреть файл

@ -12,69 +12,21 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "base/containers/stack_container.h" #include "mozilla/Mutex.h"
#include "base/lazy_instance.h" #include "mozilla/RandomNum.h"
#include "nsTArray.h"
#include "base/logging.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/event.h"
#include "mojo/core/ports/node_delegate.h" #include "mojo/core/ports/node_delegate.h"
#include "mojo/core/ports/port_locker.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 mojo {
namespace core { namespace core {
namespace ports { namespace ports {
namespace { 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<RandomNameGenerator>::Leaky g_name_generator =
LAZY_INSTANCE_INITIALIZER;
int DebugError(const char* message, int error_code) { int DebugError(const char* message, int error_code) {
NOTREACHED() << "Oops: " << message; NOTREACHED() << "Oops: " << message;
return error_code; return error_code;
@ -97,7 +49,10 @@ bool CanAcceptMoreMessages(const Port* port) {
} }
void GenerateRandomPortName(PortName* name) { 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 } // namespace
@ -111,10 +66,10 @@ Node::~Node() {
bool Node::CanShutdownCleanly(ShutdownPolicy policy) { bool Node::CanShutdownCleanly(ShutdownPolicy policy) {
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock ports_lock(ports_lock_); mozilla::MutexAutoLock ports_lock(ports_lock_);
if (policy == ShutdownPolicy::DONT_ALLOW_LOCAL_PORTS) { if (policy == ShutdownPolicy::DONT_ALLOW_LOCAL_PORTS) {
#if DCHECK_IS_ON() #ifdef DEBUG
for (auto& entry : ports_) { for (auto& entry : ports_) {
DVLOG(2) << "Port " << entry.first << " referencing node " DVLOG(2) << "Port " << entry.first << " referencing node "
<< entry.second->peer_node_name << " is blocking shutdown of " << entry.second->peer_node_name << " is blocking shutdown of "
@ -136,7 +91,7 @@ bool Node::CanShutdownCleanly(ShutdownPolicy policy) {
auto* port = locker.port(); auto* port = locker.port();
if (port->peer_node_name != name_ && port->state != Port::kReceiving) { if (port->peer_node_name != name_ && port->state != Port::kReceiving) {
can_shutdown = false; can_shutdown = false;
#if DCHECK_IS_ON() #ifdef DEBUG
DVLOG(2) << "Port " << entry.first << " referencing node " DVLOG(2) << "Port " << entry.first << " referencing node "
<< port->peer_node_name << " is blocking shutdown of " << port->peer_node_name << " is blocking shutdown of "
<< "node " << name_ << " (state=" << port->state << ")"; << "node " << name_ << " (state=" << port->state << ")";
@ -152,7 +107,7 @@ bool Node::CanShutdownCleanly(ShutdownPolicy policy) {
int Node::GetPort(const PortName& port_name, PortRef* port_ref) { int Node::GetPort(const PortName& port_name, PortRef* port_ref) {
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock lock(ports_lock_); mozilla::MutexAutoLock lock(ports_lock_);
auto iter = ports_.find(port_name); auto iter = ports_.find(port_name);
if (iter == ports_.end()) return ERROR_PORT_UNKNOWN; if (iter == ports_.end()) return ERROR_PORT_UNKNOWN;
@ -169,7 +124,7 @@ int Node::CreateUninitializedPort(PortRef* port_ref) {
PortName port_name; PortName port_name;
GenerateRandomPortName(&port_name); GenerateRandomPortName(&port_name);
scoped_refptr<Port> port(new Port(kInitialSequenceNum, kInitialSequenceNum)); RefPtr<Port> port(new Port(kInitialSequenceNum, kInitialSequenceNum));
int rv = AddPortWithName(port_name, port); int rv = AddPortWithName(port_name, port);
if (rv != OK) return rv; if (rv != OK) return rv;
@ -183,7 +138,7 @@ int Node::InitializePort(const PortRef& port_ref,
{ {
// Must be acquired for UpdatePortPeerAddress below. // Must be acquired for UpdatePortPeerAddress below.
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock ports_locker(ports_lock_); mozilla::MutexAutoLock ports_lock(ports_lock_);
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
auto* port = locker.port(); auto* port = locker.port();
@ -217,8 +172,7 @@ int Node::CreatePortPair(PortRef* port0_ref, PortRef* port1_ref) {
return OK; return OK;
} }
int Node::SetUserData(const PortRef& port_ref, int Node::SetUserData(const PortRef& port_ref, RefPtr<UserData> user_data) {
scoped_refptr<UserData> user_data) {
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
auto* port = locker.port(); auto* port = locker.port();
if (port->state == Port::kClosed) return ERROR_PORT_STATE_UNEXPECTED; if (port->state == Port::kClosed) return ERROR_PORT_STATE_UNEXPECTED;
@ -228,8 +182,7 @@ int Node::SetUserData(const PortRef& port_ref,
return OK; return OK;
} }
int Node::GetUserData(const PortRef& port_ref, int Node::GetUserData(const PortRef& port_ref, RefPtr<UserData>* user_data) {
scoped_refptr<UserData>* user_data) {
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
auto* port = locker.port(); auto* port = locker.port();
if (port->state == Port::kClosed) return ERROR_PORT_STATE_UNEXPECTED; 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) { int Node::ClosePort(const PortRef& port_ref) {
std::vector<std::unique_ptr<UserMessageEvent>> undelivered_messages; std::vector<mozilla::UniquePtr<UserMessageEvent>> undelivered_messages;
NodeName peer_node_name; NodeName peer_node_name;
PortName peer_port_name; PortName peer_port_name;
uint64_t last_sequence_num = 0; 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() << "@" DVLOG(2) << "Sending ObserveClosure from " << port_ref.name() << "@"
<< name_ << " to " << peer_port_name << "@" << peer_node_name; << name_ << " to " << peer_port_name << "@" << peer_node_name;
delegate_->ForwardEvent(peer_node_name, delegate_->ForwardEvent(peer_node_name,
std::make_unique<ObserveClosureEvent>( mozilla::MakeUnique<ObserveClosureEvent>(
peer_port_name, last_sequence_num)); peer_port_name, last_sequence_num));
for (const auto& message : undelivered_messages) { for (const auto& message : undelivered_messages) {
for (size_t i = 0; i < message->num_ports(); ++i) { 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, int Node::GetMessage(const PortRef& port_ref,
std::unique_ptr<UserMessageEvent>* message, mozilla::UniquePtr<UserMessageEvent>* message,
MessageFilter* filter) { MessageFilter* filter) {
*message = nullptr; *message = nullptr;
@ -336,7 +289,7 @@ int Node::GetMessage(const PortRef& port_ref,
if (*message && if (*message &&
(*message)->sequence_num() == port->sequence_num_to_acknowledge) { (*message)->sequence_num() == port->sequence_num_to_acknowledge) {
peer_node_name = port->peer_node_name; peer_node_name = port->peer_node_name;
ack_event = std::make_unique<UserMessageReadAckEvent>( ack_event = mozilla::MakeUnique<UserMessageReadAckEvent>(
port->peer_port_name, port->sequence_num_to_acknowledge); 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, int Node::SendUserMessage(const PortRef& port_ref,
std::unique_ptr<UserMessageEvent> message) { mozilla::UniquePtr<UserMessageEvent> message) {
int rv = SendUserMessageInternal(port_ref, &message); int rv = SendUserMessageInternal(port_ref, &message);
if (rv != OK) { if (rv != OK) {
// If send failed, close all carried ports. Note that we're careful not to // 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, delegate_->ForwardEvent(peer_node_name,
std::make_unique<UserMessageReadAckRequestEvent>( mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
peer_port_name, sequence_num_to_request_ack)); peer_port_name, sequence_num_to_request_ack));
return OK; return OK;
} }
@ -439,7 +392,7 @@ int Node::MergePorts(const PortRef& port_ref,
{ {
// Must be held for ConvertToProxy. // Must be held for ConvertToProxy.
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock ports_locker(ports_lock_); mozilla::MutexAutoLock ports_locker(ports_lock_);
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
@ -464,8 +417,8 @@ int Node::MergePorts(const PortRef& port_ref,
delegate_->ForwardEvent( delegate_->ForwardEvent(
destination_node_name, destination_node_name,
std::make_unique<MergePortEvent>(destination_port_name, new_port_name, mozilla::MakeUnique<MergePortEvent>(destination_port_name, new_port_name,
new_port_descriptor)); new_port_descriptor));
return OK; return OK;
} }
@ -487,10 +440,10 @@ int Node::LostConnectionToNode(const NodeName& node_name) {
return OK; return OK;
} }
int Node::OnUserMessage(std::unique_ptr<UserMessageEvent> message) { int Node::OnUserMessage(mozilla::UniquePtr<UserMessageEvent> message) {
PortName port_name = message->port_name(); PortName port_name = message->port_name();
#if DCHECK_IS_ON() #ifdef DEBUG
std::ostringstream ports_buf; std::ostringstream ports_buf;
for (size_t i = 0; i < message->num_ports(); ++i) { for (size_t i = 0; i < message->num_ports(); ++i) {
if (i > 0) ports_buf << ","; if (i > 0) ports_buf << ",";
@ -574,11 +527,11 @@ int Node::OnUserMessage(std::unique_ptr<UserMessageEvent> message) {
return OK; return OK;
} }
int Node::OnPortAccepted(std::unique_ptr<PortAcceptedEvent> event) { int Node::OnPortAccepted(mozilla::UniquePtr<PortAcceptedEvent> event) {
PortRef port_ref; PortRef port_ref;
if (GetPort(event->port_name(), &port_ref) != OK) return ERROR_PORT_UNKNOWN; if (GetPort(event->port_name(), &port_ref) != OK) return ERROR_PORT_UNKNOWN;
#if DCHECK_IS_ON() #ifdef DEBUG
{ {
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
DVLOG(2) << "PortAccepted at " << port_ref.name() << "@" << name_ DVLOG(2) << "PortAccepted at " << port_ref.name() << "@" << name_
@ -590,7 +543,7 @@ int Node::OnPortAccepted(std::unique_ptr<PortAcceptedEvent> event) {
return BeginProxying(port_ref); return BeginProxying(port_ref);
} }
int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) { int Node::OnObserveProxy(mozilla::UniquePtr<ObserveProxyEvent> event) {
if (event->port_name() == kInvalidPortName) { if (event->port_name() == kInvalidPortName) {
// An ObserveProxy with an invalid target port name is a broadcast used to // 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 // inform ports when their peer (which was itself a proxy) has become
@ -627,7 +580,7 @@ int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) {
{ {
// Must be acquired for UpdatePortPeerAddress below. // Must be acquired for UpdatePortPeerAddress below.
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock ports_locker(ports_lock_); mozilla::MutexAutoLock ports_locker(ports_lock_);
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
auto* port = locker.port(); auto* port = locker.port();
@ -639,7 +592,7 @@ int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) {
event->proxy_target_node_name(), event->proxy_target_node_name(),
event->proxy_target_port_name()); event->proxy_target_port_name());
event_target_node = event->proxy_node_name(); event_target_node = event->proxy_node_name();
event_to_forward = std::make_unique<ObserveProxyAckEvent>( event_to_forward = mozilla::MakeUnique<ObserveProxyAckEvent>(
event->proxy_port_name(), port->next_sequence_num_to_send - 1); event->proxy_port_name(), port->next_sequence_num_to_send - 1);
peer_changed = true; peer_changed = true;
DVLOG(2) << "Forwarding ObserveProxyAck from " << event->port_name() DVLOG(2) << "Forwarding ObserveProxyAck from " << event->port_name()
@ -660,10 +613,10 @@ int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) {
<< "@" << event->proxy_node_name(); << "@" << event->proxy_node_name();
port->send_on_proxy_removal = port->send_on_proxy_removal =
std::make_unique<std::pair<NodeName, ScopedEvent>>( mozilla::MakeUnique<std::pair<NodeName, ScopedEvent>>(
event->proxy_node_name(), event->proxy_node_name(),
std::make_unique<ObserveProxyAckEvent>(event->proxy_port_name(), mozilla::MakeUnique<ObserveProxyAckEvent>(
kInvalidSequenceNum)); event->proxy_port_name(), kInvalidSequenceNum));
} }
} else { } else {
// Forward this event along to our peer. Eventually, it should find the // Forward this event along to our peer. Eventually, it should find the
@ -689,7 +642,7 @@ int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) {
return OK; return OK;
} }
int Node::OnObserveProxyAck(std::unique_ptr<ObserveProxyAckEvent> event) { int Node::OnObserveProxyAck(mozilla::UniquePtr<ObserveProxyAckEvent> event) {
DVLOG(2) << "ObserveProxyAck at " << event->port_name() << "@" << name_ DVLOG(2) << "ObserveProxyAck at " << event->port_name() << "@" << name_
<< " (last_sequence_num=" << event->last_sequence_num() << ")"; << " (last_sequence_num=" << event->last_sequence_num() << ")";
@ -725,7 +678,7 @@ int Node::OnObserveProxyAck(std::unique_ptr<ObserveProxyAckEvent> event) {
return OK; return OK;
} }
int Node::OnObserveClosure(std::unique_ptr<ObserveClosureEvent> event) { int Node::OnObserveClosure(mozilla::UniquePtr<ObserveClosureEvent> event) {
// OK if the port doesn't exist, as it may have been closed already. // OK if the port doesn't exist, as it may have been closed already.
PortRef port_ref; PortRef port_ref;
if (GetPort(event->port_name(), &port_ref) != OK) return OK; if (GetPort(event->port_name(), &port_ref) != OK) return OK;
@ -799,7 +752,7 @@ int Node::OnObserveClosure(std::unique_ptr<ObserveClosureEvent> event) {
return OK; return OK;
} }
int Node::OnMergePort(std::unique_ptr<MergePortEvent> event) { int Node::OnMergePort(mozilla::UniquePtr<MergePortEvent> event) {
PortRef port_ref; PortRef port_ref;
GetPort(event->port_name(), &port_ref); GetPort(event->port_name(), &port_ref);
@ -835,7 +788,7 @@ int Node::OnMergePort(std::unique_ptr<MergePortEvent> event) {
} }
int Node::OnUserMessageReadAckRequest( int Node::OnUserMessageReadAckRequest(
std::unique_ptr<UserMessageReadAckRequestEvent> event) { mozilla::UniquePtr<UserMessageReadAckRequestEvent> event) {
PortRef port_ref; PortRef port_ref;
GetPort(event->port_name(), &port_ref); GetPort(event->port_name(), &port_ref);
@ -845,7 +798,7 @@ int Node::OnUserMessageReadAckRequest(
if (!port_ref.is_valid()) return ERROR_PORT_UNKNOWN; if (!port_ref.is_valid()) return ERROR_PORT_UNKNOWN;
NodeName peer_node_name; NodeName peer_node_name;
std::unique_ptr<Event> event_to_send; mozilla::UniquePtr<Event> event_to_send;
{ {
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
auto* port = locker.port(); auto* port = locker.port();
@ -863,7 +816,7 @@ int Node::OnUserMessageReadAckRequest(
if (current_sequence_num >= event->sequence_num_to_acknowledge()) { if (current_sequence_num >= event->sequence_num_to_acknowledge()) {
// If the current sequence number to read already exceeds the ack // If the current sequence number to read already exceeds the ack
// request, send an ack immediately. // request, send an ack immediately.
event_to_send = std::make_unique<UserMessageReadAckEvent>( event_to_send = mozilla::MakeUnique<UserMessageReadAckEvent>(
port->peer_port_name, current_sequence_num); port->peer_port_name, current_sequence_num);
// This might be a late or duplicate acknowledge request, that's // This might be a late or duplicate acknowledge request, that's
@ -897,7 +850,8 @@ int Node::OnUserMessageReadAckRequest(
return OK; return OK;
} }
int Node::OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> event) { int Node::OnUserMessageReadAck(
mozilla::UniquePtr<UserMessageReadAckEvent> event) {
PortRef port_ref; PortRef port_ref;
GetPort(event->port_name(), &port_ref); GetPort(event->port_name(), &port_ref);
@ -929,7 +883,7 @@ int Node::OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> event) {
// not been closed. // not been closed.
if (port->sequence_num_acknowledge_interval && !port->peer_closed) { if (port->sequence_num_acknowledge_interval && !port->peer_closed) {
peer_node_name = port->peer_node_name; peer_node_name = port->peer_node_name;
ack_request_event = std::make_unique<UserMessageReadAckRequestEvent>( ack_request_event = mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
port->peer_port_name, port->last_sequence_num_acknowledged + port->peer_port_name, port->last_sequence_num_acknowledged +
port->sequence_num_acknowledge_interval); port->sequence_num_acknowledge_interval);
} }
@ -942,9 +896,9 @@ int Node::OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> event) {
return OK; return OK;
} }
int Node::AddPortWithName(const PortName& port_name, scoped_refptr<Port> port) { int Node::AddPortWithName(const PortName& port_name, RefPtr<Port> port) {
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock lock(ports_lock_); mozilla::MutexAutoLock lock(ports_lock_);
if (port->peer_port_name != kInvalidPortName) { if (port->peer_port_name != kInvalidPortName) {
DCHECK_NE(kInvalidNodeName, port->peer_node_name); DCHECK_NE(kInvalidNodeName, port->peer_node_name);
peer_port_maps_[port->peer_node_name][port->peer_port_name].emplace( 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> port) {
void Node::ErasePort(const PortName& port_name) { void Node::ErasePort(const PortName& port_name) {
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
scoped_refptr<Port> port; RefPtr<Port> port;
{ {
base::AutoLock lock(ports_lock_); mozilla::MutexAutoLock lock(ports_lock_);
auto it = ports_.find(port_name); auto it = ports_.find(port_name);
if (it == ports_.end()) return; if (it == ports_.end()) return;
port = std::move(it->second); 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 // NOTE: We are careful not to release the port's messages while holding any
// locks, since they may run arbitrary user code upon destruction. // locks, since they may run arbitrary user code upon destruction.
std::vector<std::unique_ptr<UserMessageEvent>> messages; std::vector<mozilla::UniquePtr<UserMessageEvent>> messages;
{ {
PortRef port_ref(port_name, std::move(port)); PortRef port_ref(port_name, std::move(port));
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
@ -979,9 +933,9 @@ void Node::ErasePort(const PortName& port_name) {
DVLOG(2) << "Deleted port " << port_name << "@" << name_; DVLOG(2) << "Deleted port " << port_name << "@" << name_;
} }
int Node::SendUserMessageInternal(const PortRef& port_ref, int Node::SendUserMessageInternal(
std::unique_ptr<UserMessageEvent>* message) { const PortRef& port_ref, mozilla::UniquePtr<UserMessageEvent>* message) {
std::unique_ptr<UserMessageEvent>& m = *message; mozilla::UniquePtr<UserMessageEvent>& m = *message;
for (size_t i = 0; i < m->num_ports(); ++i) { for (size_t i = 0; i < m->num_ports(); ++i) {
if (m->ports()[i] == port_ref.name()) return ERROR_PORT_CANNOT_SEND_SELF; 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. // Needed to swap peer map entries below.
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::ReleasableAutoLock ports_locker(&ports_lock_); mozilla::Maybe<mozilla::MutexAutoLock> ports_locker(std::in_place,
ports_lock_);
base::Optional<PortLocker> locker(base::in_place, port_refs, 2); mozilla::Maybe<PortLocker> locker(std::in_place, port_refs, size_t(2));
auto* port0 = locker->GetPort(port0_ref); auto* port0 = locker->GetPort(port0_ref);
auto* port1 = locker->GetPort(port1_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 = const bool close_port1 =
port1->state == Port::kReceiving || allow_close_on_bad_state; port1->state == Port::kReceiving || allow_close_on_bad_state;
locker.reset(); locker.reset();
ports_locker.Release(); ports_locker.reset();
if (close_port0) ClosePort(port0_ref); if (close_port0) ClosePort(port0_ref);
if (close_port1) ClosePort(port1_ref); if (close_port1) ClosePort(port1_ref);
return ERROR_PORT_STATE_UNEXPECTED; 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 // If either end of the port cycle is closed, we propagate an
// ObserveClosure event. // ObserveClosure event.
closure_event_target_node = port->peer_node_name; closure_event_target_node = port->peer_node_name;
closure_event = std::make_unique<ObserveClosureEvent>( closure_event = mozilla::MakeUnique<ObserveClosureEvent>(
port->peer_port_name, port->last_sequence_num_to_receive); 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. // consistent state by undoing the peer swap and closing the ports.
{ {
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock ports_locker(ports_lock_); mozilla::MutexAutoLock ports_locker(ports_lock_);
PortLocker locker(port_refs, 2); PortLocker locker(port_refs, 2);
auto* port0 = locker.GetPort(port0_ref); auto* port0 = locker.GetPort(port0_ref);
auto* port1 = locker.GetPort(port1_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, int Node::AcceptPort(const PortName& port_name,
const Event::PortDescriptor& port_descriptor) { const Event::PortDescriptor& port_descriptor) {
scoped_refptr<Port> port = RefPtr<Port> port =
base::MakeRefCounted<Port>(port_descriptor.next_sequence_num_to_send, mozilla::MakeRefPtr<Port>(port_descriptor.next_sequence_num_to_send,
port_descriptor.next_sequence_num_to_receive); port_descriptor.next_sequence_num_to_receive);
port->state = Port::kReceiving; port->state = Port::kReceiving;
port->peer_node_name = port_descriptor.peer_node_name; port->peer_node_name = port_descriptor.peer_node_name;
port->peer_port_name = port_descriptor.peer_port_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; if (rv != OK) return rv;
// Allow referring port to forward messages. // Allow referring port to forward messages.
delegate_->ForwardEvent( delegate_->ForwardEvent(port_descriptor.referring_node_name,
port_descriptor.referring_node_name, mozilla::MakeUnique<PortAcceptedEvent>(
std::make_unique<PortAcceptedEvent>(port_descriptor.referring_port_name)); port_descriptor.referring_port_name));
return OK; 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. // it only while no port locks are held on the calling thread.
if (target_node_name != name_) { if (target_node_name != name_) {
if (!message->NotifyWillBeRoutedExternally()) { if (!message->NotifyWillBeRoutedExternally()) {
LOG(ERROR) << "NotifyWillBeRoutedExternally failed unexpectedly."; CHROMIUM_LOG(ERROR)
<< "NotifyWillBeRoutedExternally failed unexpectedly.";
return ERROR_PORT_STATE_UNEXPECTED; return ERROR_PORT_STATE_UNEXPECTED;
} }
} }
// Must be held because ConvertToProxy needs to update |peer_port_maps_|. // Must be held because ConvertToProxy needs to update |peer_port_maps_|.
PortLocker::AssertNoPortsLockedOnCurrentThread(); 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. // Simultaneously lock the forwarding port as well as all attached ports.
base::StackVector<PortRef, 4> attached_port_refs; AutoTArray<PortRef, 4> attached_port_refs;
base::StackVector<const PortRef*, 5> ports_to_lock; AutoTArray<const PortRef*, 5> ports_to_lock;
attached_port_refs.container().resize(message->num_ports()); attached_port_refs.SetCapacity(message->num_ports());
ports_to_lock.container().resize(message->num_ports() + 1); ports_to_lock.SetCapacity(message->num_ports() + 1);
ports_to_lock[0] = &forwarding_port_ref; ports_to_lock.AppendElement(&forwarding_port_ref);
for (size_t i = 0; i < message->num_ports(); ++i) { for (size_t i = 0; i < message->num_ports(); ++i) {
const PortName& attached_port_name = message->ports()[i]; const PortName& attached_port_name = message->ports()[i];
auto iter = ports_.find(attached_port_name); auto iter = ports_.find(attached_port_name);
DCHECK(iter != ports_.end()); DCHECK(iter != ports_.end());
attached_port_refs[i] = PortRef(attached_port_name, iter->second); attached_port_refs.AppendElement(
ports_to_lock[i + 1] = &attached_port_refs[i]; PortRef(attached_port_name, iter->second));
ports_to_lock.AppendElement(&attached_port_refs[i]);
} }
PortLocker locker(ports_to_lock.container().data(), PortLocker locker(ports_to_lock.Elements(), ports_to_lock.Length());
ports_to_lock.container().size());
auto* forwarding_port = locker.GetPort(forwarding_port_ref); auto* forwarding_port = locker.GetPort(forwarding_port_ref);
if (forwarding_port->peer_node_name != target_node_name) { 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. // a proxy. Otherwise, use the next outgoing sequence number.
if (message->sequence_num() == 0) if (message->sequence_num() == 0)
message->set_sequence_num(forwarding_port->next_sequence_num_to_send++); message->set_sequence_num(forwarding_port->next_sequence_num_to_send++);
#if DCHECK_IS_ON() #ifdef DEBUG
std::ostringstream ports_buf; std::ostringstream ports_buf;
for (size_t i = 0; i < message->num_ports(); ++i) { for (size_t i = 0; i < message->num_ports(); ++i) {
if (i > 0) ports_buf << ","; 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. // 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 // They must all be in the |kReceiving| state and must not be the sender's
// own peer. // 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) { for (size_t i = 0; i < message->num_ports(); ++i) {
auto* attached_port = locker.GetPort(attached_port_refs[i]); auto* attached_port = locker.GetPort(attached_port_refs[i]);
int error = OK; 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() DVLOG(4) << "Sending message " << message->sequence_num()
<< " [ports=" << ports_buf.str() << "]" << " [ports=" << ports_buf.str() << "]"
<< " from " << forwarding_port_ref.name() << "@" << name_ << " to " << " from " << forwarding_port_ref.name() << "@" << name_ << " to "
@ -1353,7 +1309,7 @@ int Node::BeginProxying(const PortRef& port_ref) {
if (try_remove_proxy_immediately) { if (try_remove_proxy_immediately) {
// Make sure we propagate closure to our current peer. // Make sure we propagate closure to our current peer.
closure_target_node = port->peer_node_name; closure_target_node = port->peer_node_name;
closure_event = std::make_unique<ObserveClosureEvent>( closure_event = mozilla::MakeUnique<ObserveClosureEvent>(
port->peer_port_name, port->last_sequence_num_to_receive); 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 // 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 // proxy removal process as we can tell when this port has seen all of the
// messages it is expected to see. // messages it is expected to see.
std::unique_ptr<UserMessageEvent> message; mozilla::UniquePtr<UserMessageEvent> message;
{ {
SinglePortLocker locker(&port_ref); SinglePortLocker locker(&port_ref);
locker.port()->message_queue.GetNextMessage(&message, nullptr); 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 // Eventually, this node will receive ObserveProxyAck (or ObserveClosure if
// the peer was closed in the meantime). // the peer was closed in the meantime).
delegate_->ForwardEvent(peer_node_name, delegate_->ForwardEvent(peer_node_name,
std::make_unique<ObserveProxyEvent>( mozilla::MakeUnique<ObserveProxyEvent>(
peer_port_name, name_, port_ref.name(), peer_port_name, name_, port_ref.name(),
peer_node_name, peer_port_name)); peer_node_name, peer_port_name));
} }
@ -1451,11 +1407,11 @@ void Node::DestroyAllPortsWithPeer(const NodeName& node_name,
std::vector<PortRef> ports_to_notify; std::vector<PortRef> ports_to_notify;
std::vector<PortName> dead_proxies_to_broadcast; std::vector<PortName> dead_proxies_to_broadcast;
std::vector<std::unique_ptr<UserMessageEvent>> undelivered_messages; std::vector<mozilla::UniquePtr<UserMessageEvent>> undelivered_messages;
{ {
PortLocker::AssertNoPortsLockedOnCurrentThread(); 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); auto node_peer_port_map_iter = peer_port_maps_.find(node_name);
if (node_peer_port_map_iter == peer_port_maps_.end()) return; 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. // inefficient but rare.
if (port->state != Port::kReceiving) { if (port->state != Port::kReceiving) {
dead_proxies_to_broadcast.push_back(local_port_ref.name()); dead_proxies_to_broadcast.push_back(local_port_ref.name());
std::vector<std::unique_ptr<UserMessageEvent>> messages; std::vector<mozilla::UniquePtr<UserMessageEvent>> messages;
port->message_queue.TakeAllMessages(&messages); port->message_queue.TakeAllMessages(&messages);
for (auto& message : messages) for (auto& message : messages)
undelivered_messages.emplace_back(std::move(message)); 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) { for (const auto& proxy_name : dead_proxies_to_broadcast) {
// Broadcast an event signifying that this proxy is no longer functioning. // Broadcast an event signifying that this proxy is no longer functioning.
delegate_->BroadcastEvent(std::make_unique<ObserveProxyEvent>( delegate_->BroadcastEvent(mozilla::MakeUnique<ObserveProxyEvent>(
kInvalidPortName, name_, proxy_name, kInvalidNodeName, kInvalidPortName, name_, proxy_name, kInvalidNodeName,
kInvalidPortName)); kInvalidPortName));
@ -1549,7 +1505,7 @@ void Node::UpdatePortPeerAddress(const PortName& local_port_name,
Port* local_port, Port* local_port,
const NodeName& new_peer_node, const NodeName& new_peer_node,
const PortName& new_peer_port) { const PortName& new_peer_port) {
ports_lock_.AssertAcquired(); ports_lock_.AssertCurrentThreadOwns();
local_port->AssertLockAcquired(); local_port->AssertLockAcquired();
RemoveFromPeerPortMap(local_port_name, local_port); 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; local_port->peer_port_name = new_peer_port;
if (new_peer_port != kInvalidPortName) { if (new_peer_port != kInvalidPortName) {
peer_port_maps_[new_peer_node][new_peer_port].emplace( peer_port_maps_[new_peer_node][new_peer_port].emplace(
local_port_name, local_port_name, PortRef(local_port_name, RefPtr<Port>{local_port}));
PortRef(local_port_name, base::WrapRefCounted<Port>(local_port)));
} }
} }
@ -1581,7 +1536,7 @@ void Node::RemoveFromPeerPortMap(const PortName& local_port_name,
void Node::SwapPortPeers(const PortName& port0_name, Port* port0, void Node::SwapPortPeers(const PortName& port0_name, Port* port0,
const PortName& port1_name, Port* port1) { const PortName& port1_name, Port* port1) {
ports_lock_.AssertAcquired(); ports_lock_.AssertCurrentThreadOwns();
port0->AssertLockAcquired(); port0->AssertLockAcquired();
port1->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]; peer_port_maps_[port1->peer_node_name][port1->peer_port_name];
peer0_ports.erase(port0_name); peer0_ports.erase(port0_name);
peer1_ports.erase(port1_name); peer1_ports.erase(port1_name);
peer0_ports.emplace(port1_name, peer0_ports.emplace(port1_name, PortRef(port1_name, RefPtr<Port>{port1}));
PortRef(port1_name, base::WrapRefCounted<Port>(port1))); peer1_ports.emplace(port0_name, PortRef(port0_name, RefPtr<Port>{port0}));
peer1_ports.emplace(port0_name,
PortRef(port0_name, base::WrapRefCounted<Port>(port0)));
std::swap(port0->peer_node_name, port1->peer_node_name); std::swap(port0->peer_node_name, port1->peer_node_name);
std::swap(port0->peer_port_name, port1->peer_port_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; if (!port->sequence_num_acknowledge_interval) return;
peer_node_name = port->peer_node_name; peer_node_name = port->peer_node_name;
ack_request_event = std::make_unique<UserMessageReadAckRequestEvent>( ack_request_event = mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
port->peer_port_name, port->last_sequence_num_acknowledged + port->peer_port_name, port->last_sequence_num_acknowledged +
port->sequence_num_acknowledge_interval); port->sequence_num_acknowledge_interval);
} }
@ -1630,7 +1583,7 @@ void Node::MaybeForwardAckRequest(const PortRef& port_ref) {
if (!port->sequence_num_to_acknowledge) return; if (!port->sequence_num_to_acknowledge) return;
peer_node_name = port->peer_node_name; peer_node_name = port->peer_node_name;
ack_request_event = std::make_unique<UserMessageReadAckRequestEvent>( ack_request_event = mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
port->peer_port_name, port->sequence_num_to_acknowledge); port->peer_port_name, port->sequence_num_to_acknowledge);
port->sequence_num_to_acknowledge = 0; 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; if (!port->sequence_num_to_acknowledge || !last_sequence_num_read) return;
peer_node_name = port->peer_node_name; peer_node_name = port->peer_node_name;
ack_event = std::make_unique<UserMessageReadAckEvent>( ack_event = mozilla::MakeUnique<UserMessageReadAckEvent>(
port->peer_port_name, last_sequence_num_read); port->peer_port_name, last_sequence_num_read);
} }
@ -1666,10 +1619,10 @@ Node::DelegateHolder::DelegateHolder(Node* node, NodeDelegate* delegate)
Node::DelegateHolder::~DelegateHolder() = default; Node::DelegateHolder::~DelegateHolder() = default;
#if DCHECK_IS_ON() #ifdef DEBUG
void Node::DelegateHolder::EnsureSafeDelegateAccess() const { void Node::DelegateHolder::EnsureSafeDelegateAccess() const {
PortLocker::AssertNoPortsLockedOnCurrentThread(); PortLocker::AssertNoPortsLockedOnCurrentThread();
base::AutoLock lock(node_->ports_lock_); mozilla::MutexAutoLock lock(node_->ports_lock_);
} }
#endif #endif

Просмотреть файл

@ -11,16 +11,13 @@
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
#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/event.h"
#include "mojo/core/ports/name.h" #include "mojo/core/ports/name.h"
#include "mojo/core/ports/port.h" #include "mojo/core/ports/port.h"
#include "mojo/core/ports/port_ref.h" #include "mojo/core/ports/port_ref.h"
#include "mojo/core/ports/user_data.h" #include "mojo/core/ports/user_data.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
@ -66,7 +63,7 @@ class NodeDelegate;
// by Nodes to coordinate Port behavior and lifetime within and across Nodes. // by Nodes to coordinate Port behavior and lifetime within and across Nodes.
// See Event documentation for description of different types of events used by // See Event documentation for description of different types of events used by
// a Node to coordinate behavior. // a Node to coordinate behavior.
class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node { class Node {
public: public:
enum class ShutdownPolicy { enum class ShutdownPolicy {
DONT_ALLOW_LOCAL_PORTS, DONT_ALLOW_LOCAL_PORTS,
@ -77,6 +74,9 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node {
Node(const NodeName& name, NodeDelegate* delegate); Node(const NodeName& name, NodeDelegate* delegate);
~Node(); ~Node();
Node(const Node&) = delete;
void operator=(const Node&) = delete;
// Returns true iff there are no open ports referring to another node or ports // 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 // 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 // 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); int CreatePortPair(PortRef* port0_ref, PortRef* port1_ref);
// User data associated with the port. // User data associated with the port.
int SetUserData(const PortRef& port_ref, scoped_refptr<UserData> user_data); int SetUserData(const PortRef& port_ref, RefPtr<UserData> user_data);
int GetUserData(const PortRef& port_ref, scoped_refptr<UserData>* user_data); int GetUserData(const PortRef& port_ref, RefPtr<UserData>* user_data);
// Prevents further messages from being sent from this port or delivered to // 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 // 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 // available. Ownership of |filter| is not taken, and it must outlive the
// extent of this call. // extent of this call.
int GetMessage(const PortRef& port_ref, int GetMessage(const PortRef& port_ref,
std::unique_ptr<UserMessageEvent>* message, mozilla::UniquePtr<UserMessageEvent>* message,
MessageFilter* filter); MessageFilter* filter);
// Sends a message from the specified port to its peer. Note that the message // Sends a message from the specified port to its peer. Note that the message
// notification may arrive synchronously (via PortStatusChanged() on the // notification may arrive synchronously (via PortStatusChanged() on the
// delegate) if the peer is local to this Node. // delegate) if the peer is local to this Node.
int SendUserMessage(const PortRef& port_ref, int SendUserMessage(const PortRef& port_ref,
std::unique_ptr<UserMessageEvent> message); mozilla::UniquePtr<UserMessageEvent> message);
// Makes the port send acknowledge requests to its conjugate to acknowledge // Makes the port send acknowledge requests to its conjugate to acknowledge
// at least every |sequence_number_acknowledge_interval| messages as they're // 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(Node* node, NodeDelegate* delegate);
~DelegateHolder(); ~DelegateHolder();
DelegateHolder(const DelegateHolder&) = delete;
void operator=(const DelegateHolder&) = delete;
NodeDelegate* operator->() const { NodeDelegate* operator->() const {
EnsureSafeDelegateAccess(); EnsureSafeDelegateAccess();
return delegate_; return delegate_;
} }
private: private:
#if DCHECK_IS_ON() #ifdef DEBUG
void EnsureSafeDelegateAccess() const; void EnsureSafeDelegateAccess() const;
#else #else
void EnsureSafeDelegateAccess() const {} void EnsureSafeDelegateAccess() const {}
@ -198,25 +201,23 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node {
Node* const node_; Node* const node_;
NodeDelegate* const delegate_; NodeDelegate* const delegate_;
DISALLOW_COPY_AND_ASSIGN(DelegateHolder);
}; };
int OnUserMessage(std::unique_ptr<UserMessageEvent> message); int OnUserMessage(mozilla::UniquePtr<UserMessageEvent> message);
int OnPortAccepted(std::unique_ptr<PortAcceptedEvent> event); int OnPortAccepted(mozilla::UniquePtr<PortAcceptedEvent> event);
int OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event); int OnObserveProxy(mozilla::UniquePtr<ObserveProxyEvent> event);
int OnObserveProxyAck(std::unique_ptr<ObserveProxyAckEvent> event); int OnObserveProxyAck(mozilla::UniquePtr<ObserveProxyAckEvent> event);
int OnObserveClosure(std::unique_ptr<ObserveClosureEvent> event); int OnObserveClosure(mozilla::UniquePtr<ObserveClosureEvent> event);
int OnMergePort(std::unique_ptr<MergePortEvent> event); int OnMergePort(mozilla::UniquePtr<MergePortEvent> event);
int OnUserMessageReadAckRequest( int OnUserMessageReadAckRequest(
std::unique_ptr<UserMessageReadAckRequestEvent> event); mozilla::UniquePtr<UserMessageReadAckRequestEvent> event);
int OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> event); int OnUserMessageReadAck(mozilla::UniquePtr<UserMessageReadAckEvent> event);
int AddPortWithName(const PortName& port_name, scoped_refptr<Port> port); int AddPortWithName(const PortName& port_name, RefPtr<Port> port);
void ErasePort(const PortName& port_name); void ErasePort(const PortName& port_name);
int SendUserMessageInternal(const PortRef& port_ref, int SendUserMessageInternal(const PortRef& port_ref,
std::unique_ptr<UserMessageEvent>* message); mozilla::UniquePtr<UserMessageEvent>* message);
int MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref, int MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref,
bool allow_close_on_bad_state); bool allow_close_on_bad_state);
void ConvertToProxy(Port* port, const NodeName& to_node_name, 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 // Because UserMessage events may execute arbitrary user code during
// destruction, it is also important to ensure that such events are never // destruction, it is also important to ensure that such events are never
// destroyed while this (or any individual Port) lock is held. // destroyed while this (or any individual Port) lock is held.
base::Lock ports_lock_; mozilla::Mutex ports_lock_{"Ports Lock"};
std::unordered_map<LocalPortName, scoped_refptr<Port>> ports_; std::unordered_map<LocalPortName, RefPtr<Port>> ports_;
// Maps a peer port name to a list of PortRefs for all local ports which have // 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 // 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 // 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 // usually 1. Hence we just use a flat_map of local PortRefs keyed on each
// local port's name. // 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 = using PeerPortMap =
std::unordered_map<PeerPortName, base::flat_map<LocalPortName, PortRef>>; std::unordered_map<PeerPortName,
std::unordered_map<LocalPortName, PortRef>>;
// A reverse mapping which can be used to find all local ports that reference // 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 // 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 // port on a peer node. The key to this map is the corresponding peer node
// name. // name.
std::unordered_map<NodeName, PeerPortMap> peer_port_maps_; std::unordered_map<NodeName, PeerPortMap> peer_port_maps_;
DISALLOW_COPY_AND_ASSIGN(Node);
}; };
} // namespace ports } // namespace ports

Просмотреть файл

@ -10,12 +10,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#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/event.h"
#include "mojo/core/ports/message_queue.h" #include "mojo/core/ports/message_queue.h"
#include "mojo/core/ports/user_data.h" #include "mojo/core/ports/user_data.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "nsISupportsImpl.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
@ -61,7 +61,9 @@ class PortLocker;
// which is only possible using a PortLocker. PortLocker ensures that // which is only possible using a PortLocker. PortLocker ensures that
// overlapping Port lock acquisitions on a single thread are always acquired in // overlapping Port lock acquisitions on a single thread are always acquired in
// a globally consistent order. // a globally consistent order.
class Port : public base::RefCountedThreadSafe<Port> { class Port {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Port)
public: public:
// The state of a given Port. A Port may only exist in one of these states at // The state of a given Port. A Port may only exist in one of these states at
// any given time. // any given time.
@ -149,12 +151,12 @@ class Port : public base::RefCountedThreadSafe<Port> {
// In some edge cases, a Node may need to remember to route a single special // 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 // event upon destruction of this (proxying) Port. That event is stashed here
// in the interim. // in the interim.
std::unique_ptr<std::pair<NodeName, ScopedEvent>> send_on_proxy_removal; mozilla::UniquePtr<std::pair<NodeName, ScopedEvent>> send_on_proxy_removal;
// Arbitrary user data attached to the Port. In practice, Mojo uses this to // 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 // stash an observer interface which can be notified about various Port state
// changes. // changes.
scoped_refptr<UserData> user_data; RefPtr<UserData> user_data;
// Indicates that this (proxying) Port has received acknowledgement that no // Indicates that this (proxying) Port has received acknowledgement that no
// new user messages will be routed to it. If |true|, the proxy will be // new user messages will be routed to it. If |true|, the proxy will be
@ -176,21 +178,17 @@ class Port : public base::RefCountedThreadSafe<Port> {
Port(uint64_t next_sequence_num_to_send, Port(uint64_t next_sequence_num_to_send,
uint64_t next_sequence_num_to_receive); uint64_t next_sequence_num_to_receive);
void AssertLockAcquired() { Port(const Port&) = delete;
#if DCHECK_IS_ON() void operator=(const Port&) = delete;
lock_.AssertAcquired();
#endif void AssertLockAcquired() { lock_.AssertCurrentThreadOwns(); }
}
private: private:
friend class base::RefCountedThreadSafe<Port>;
friend class PortLocker; friend class PortLocker;
~Port(); ~Port();
base::Lock lock_; mozilla::Mutex lock_{"Port State"};
DISALLOW_COPY_AND_ASSIGN(Port);
}; };
} // namespace ports } // namespace ports

Просмотреть файл

@ -8,8 +8,8 @@
#include "mojo/core/ports/port.h" #include "mojo/core/ports/port.h"
#if DCHECK_IS_ON() #ifdef DEBUG
# include "base/threading/thread_local.h" # include "base/thread_local.h"
#endif #endif
namespace mojo { namespace mojo {
@ -18,7 +18,7 @@ namespace ports {
namespace { namespace {
#if DCHECK_IS_ON() #ifdef DEBUG
void UpdateTLS(PortLocker* old_locker, PortLocker* new_locker) { void UpdateTLS(PortLocker* old_locker, PortLocker* new_locker) {
// Sanity check when DCHECK is on to make sure there is only ever one // Sanity check when DCHECK is on to make sure there is only ever one
// PortLocker extant on the current thread. // 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) PortLocker::PortLocker(const PortRef** port_refs, size_t num_ports)
: port_refs_(port_refs), num_ports_(num_ports) { : port_refs_(port_refs), num_ports_(num_ports) {
#if DCHECK_IS_ON() #ifdef DEBUG
UpdateTLS(nullptr, this); UpdateTLS(nullptr, this);
#endif #endif
@ -43,20 +43,19 @@ PortLocker::PortLocker(const PortRef** port_refs, size_t num_ports)
for (size_t i = 0; i < num_ports_; ++i) { for (size_t i = 0; i < num_ports_; ++i) {
// TODO(crbug.com/725605): Remove this CHECK. // TODO(crbug.com/725605): Remove this CHECK.
CHECK(port_refs_[i]->port()); CHECK(port_refs_[i]->port());
port_refs_[i]->port()->lock_.Acquire(); port_refs_[i]->port()->lock_.Lock();
} }
} }
PortLocker::~PortLocker() { PortLocker::~PortLocker() {
for (size_t i = 0; i < num_ports_; ++i) for (size_t i = 0; i < num_ports_; ++i) port_refs_[i]->port()->lock_.Unlock();
port_refs_[i]->port()->lock_.Release();
#if DCHECK_IS_ON() #ifdef DEBUG
UpdateTLS(this, nullptr); UpdateTLS(this, nullptr);
#endif #endif
} }
#if DCHECK_IS_ON() #ifdef DEBUG
// static // static
void PortLocker::AssertNoPortsLockedOnCurrentThread() { void PortLocker::AssertNoPortsLockedOnCurrentThread() {
// Forces a DCHECK if the TLS PortLocker is anything other than null. // Forces a DCHECK if the TLS PortLocker is anything other than null.

Просмотреть файл

@ -7,7 +7,7 @@
#include <stdint.h> #include <stdint.h>
#include "base/macros.h" #include "base/logging.h"
#include "mojo/core/ports/port_ref.h" #include "mojo/core/ports/port_ref.h"
namespace mojo { namespace mojo {
@ -31,14 +31,17 @@ class PortLocker {
PortLocker(const PortRef** port_refs, size_t num_ports); PortLocker(const PortRef** port_refs, size_t num_ports);
~PortLocker(); ~PortLocker();
PortLocker(const PortLocker&) = delete;
void operator=(const PortLocker&) = delete;
// Provides safe access to a PortRef's Port. Note that in release builds this // 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 // 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 // |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 // the state, thus minimizing the likelihood that they'll go and do something
// stupid. // stupid.
Port* GetPort(const PortRef& port_ref) const { Port* GetPort(const PortRef& port_ref) const {
#if DCHECK_IS_ON() #ifdef DEBUG
// Sanity check when DCHECK is on to ensure this is actually a port whose // Sanity check when DEBUG is on to ensure this is actually a port whose
// lock is held by this PortLocker. // lock is held by this PortLocker.
bool is_port_locked = false; bool is_port_locked = false;
for (size_t i = 0; i < num_ports_ && !is_port_locked; ++i) 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 // 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. // current thread. In non-DCHECK builds this is a no-op.
#if DCHECK_IS_ON() #ifdef DEBUG
static void AssertNoPortsLockedOnCurrentThread(); static void AssertNoPortsLockedOnCurrentThread();
#else #else
static void AssertNoPortsLockedOnCurrentThread() {} static void AssertNoPortsLockedOnCurrentThread() {}
@ -59,8 +62,6 @@ class PortLocker {
private: private:
const PortRef** const port_refs_; const PortRef** const port_refs_;
const size_t num_ports_; const size_t num_ports_;
DISALLOW_COPY_AND_ASSIGN(PortLocker);
}; };
// Convenience wrapper for a PortLocker that locks a single port. // Convenience wrapper for a PortLocker that locks a single port.
@ -69,13 +70,14 @@ class SinglePortLocker {
explicit SinglePortLocker(const PortRef* port_ref); explicit SinglePortLocker(const PortRef* port_ref);
~SinglePortLocker(); ~SinglePortLocker();
SinglePortLocker(const SinglePortLocker&) = delete;
void operator=(const SinglePortLocker&) = delete;
Port* port() const { return locker_.GetPort(*port_ref_); } Port* port() const { return locker_.GetPort(*port_ref_); }
private: private:
const PortRef* port_ref_; const PortRef* port_ref_;
PortLocker locker_; PortLocker locker_;
DISALLOW_COPY_AND_ASSIGN(SinglePortLocker);
}; };
} // namespace ports } // namespace ports

Просмотреть файл

@ -14,7 +14,7 @@ PortRef::~PortRef() = default;
PortRef::PortRef() = default; PortRef::PortRef() = default;
PortRef::PortRef(const PortName& name, scoped_refptr<Port> port) PortRef::PortRef(const PortName& name, RefPtr<Port> port)
: name_(name), port_(std::move(port)) {} : name_(name), port_(std::move(port)) {}
PortRef::PortRef(const PortRef& other) = default; PortRef::PortRef(const PortRef& other) = default;

Просмотреть файл

@ -5,9 +5,8 @@
#ifndef MOJO_CORE_PORTS_PORT_REF_H_ #ifndef MOJO_CORE_PORTS_PORT_REF_H_
#define 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 "mojo/core/ports/name.h"
#include "mozilla/RefPtr.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
@ -16,11 +15,11 @@ namespace ports {
class Port; class Port;
class PortLocker; class PortLocker;
class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortRef { class PortRef {
public: public:
~PortRef(); ~PortRef();
PortRef(); PortRef();
PortRef(const PortName& name, scoped_refptr<Port> port); PortRef(const PortName& name, RefPtr<Port> port);
PortRef(const PortRef& other); PortRef(const PortRef& other);
PortRef(PortRef&& other); PortRef(PortRef&& other);
@ -38,7 +37,7 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortRef {
Port* port() const { return port_.get(); } Port* port() const { return port_.get(); }
PortName name_; PortName name_;
scoped_refptr<Port> port_; RefPtr<Port> port_;
}; };
} // namespace ports } // namespace ports

Просмотреть файл

@ -5,16 +5,16 @@
#ifndef MOJO_CORE_PORTS_USER_DATA_H_ #ifndef MOJO_CORE_PORTS_USER_DATA_H_
#define 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 mojo {
namespace core { namespace core {
namespace ports { namespace ports {
class UserData : public base::RefCountedThreadSafe<UserData> { class UserData {
protected: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UserData);
friend class base::RefCountedThreadSafe<UserData>;
protected:
virtual ~UserData() = default; virtual ~UserData() = default;
}; };

Просмотреть файл

@ -7,9 +7,6 @@
#include <stddef.h> #include <stddef.h>
#include "base/component_export.h"
#include "base/macros.h"
namespace mojo { namespace mojo {
namespace core { namespace core {
namespace ports { namespace ports {
@ -24,13 +21,16 @@ namespace ports {
// |kUserMessageTypeInfo| and pass its address down to the UserMessage // |kUserMessageTypeInfo| and pass its address down to the UserMessage
// constructor. The type of a UserMessage can then be dynamically inspected by // constructor. The type of a UserMessage can then be dynamically inspected by
// comparing |type_info()| to any subclass's |&kUserMessageTypeInfo|. // comparing |type_info()| to any subclass's |&kUserMessageTypeInfo|.
class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessage { class UserMessage {
public: public:
struct TypeInfo {}; struct TypeInfo {};
explicit UserMessage(const TypeInfo* type_info); explicit UserMessage(const TypeInfo* type_info);
virtual ~UserMessage(); virtual ~UserMessage();
UserMessage(const UserMessage&) = delete;
void operator=(const UserMessage&) = delete;
const TypeInfo* type_info() const { return type_info_; } const TypeInfo* type_info() const { return type_info_; }
// Invoked immediately before the system asks the embedder to forward this // Invoked immediately before the system asks the embedder to forward this
@ -47,8 +47,6 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessage {
private: private:
const TypeInfo* const type_info_; const TypeInfo* const type_info_;
DISALLOW_COPY_AND_ASSIGN(UserMessage);
}; };
} // namespace ports } // namespace ports