зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
2a2037d8e9
Коммит
8381830670
|
@ -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:
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
namespace base {
|
||||
|
||||
#define DVLOG(x) CHROMIUM_LOG(ERROR)
|
||||
#define CHECK_GT DCHECK_GT
|
||||
#define CHECK_LT DCHECK_LT
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 "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<UserMessage> message) {
|
||||
void UserMessageEvent::AttachMessage(mozilla::UniquePtr<UserMessage> 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<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);
|
||||
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);
|
||||
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<const PortDescriptor*>(data + 1);
|
||||
|
@ -198,7 +198,7 @@ ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name,
|
|||
const auto* in_names =
|
||||
reinterpret_cast<const PortName*>(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_t> size = sizeof(UserMessageEventData);
|
||||
base::CheckedNumeric<size_t> ports_size =
|
||||
mozilla::CheckedInt<size_t> size = sizeof(UserMessageEventData);
|
||||
mozilla::CheckedInt<size_t> ports_size =
|
||||
sizeof(PortDescriptor) + sizeof(PortName);
|
||||
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 {
|
||||
DCHECK_EQ(ports_.size(), port_descriptors_.size());
|
||||
auto* data = static_cast<UserMessageEventData*>(buffer);
|
||||
data->sequence_num = sequence_num_;
|
||||
DCHECK(base::IsValueInRangeForNumericType<uint32_t>(ports_.size()));
|
||||
data->num_ports = static_cast<uint32_t>(ports_.size());
|
||||
mozilla::CheckedInt<uint32_t> num_ports{ports_.size()};
|
||||
DCHECK(num_ports.isValid());
|
||||
data->num_ports = num_ports.value();
|
||||
data->padding = 0;
|
||||
|
||||
auto* ports_data = reinterpret_cast<PortDescriptor*>(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<PortAcceptedEvent>(port_name);
|
||||
return mozilla::MakeUnique<PortAcceptedEvent>(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<const ObserveProxyEventData*>(buffer);
|
||||
return std::make_unique<ObserveProxyEvent>(
|
||||
return mozilla::MakeUnique<ObserveProxyEvent>(
|
||||
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<ObserveProxyEvent>(
|
||||
return mozilla::MakeUnique<ObserveProxyEvent>(
|
||||
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<const ObserveProxyAckEventData*>(buffer);
|
||||
return std::make_unique<ObserveProxyAckEvent>(port_name,
|
||||
data->last_sequence_num);
|
||||
return mozilla::MakeUnique<ObserveProxyAckEvent>(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<ObserveProxyAckEvent>(port_name(),
|
||||
last_sequence_num_);
|
||||
return mozilla::MakeUnique<ObserveProxyAckEvent>(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<const ObserveClosureEventData*>(buffer);
|
||||
return std::make_unique<ObserveClosureEvent>(port_name,
|
||||
data->last_sequence_num);
|
||||
return mozilla::MakeUnique<ObserveClosureEvent>(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<ObserveClosureEvent>(port_name(), last_sequence_num_);
|
||||
return mozilla::MakeUnique<ObserveClosureEvent>(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<const MergePortEventData*>(buffer);
|
||||
return std::make_unique<MergePortEvent>(port_name, data->new_port_name,
|
||||
data->new_port_descriptor);
|
||||
return mozilla::MakeUnique<MergePortEvent>(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<const UserMessageReadAckRequestEventData*>(buffer);
|
||||
return std::make_unique<UserMessageReadAckRequestEvent>(
|
||||
return mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
|
||||
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<const UserMessageReadAckEventData*>(buffer);
|
||||
return std::make_unique<UserMessageReadAckEvent>(
|
||||
return mozilla::MakeUnique<UserMessageReadAckEvent>(
|
||||
port_name, data->sequence_num_acknowledged);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#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/user_message.h"
|
||||
|
||||
|
@ -21,11 +19,11 @@ namespace ports {
|
|||
|
||||
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
|
||||
// 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 <typename T>
|
||||
static std::unique_ptr<T> Cast(ScopedEvent* event) {
|
||||
return base::WrapUnique(static_cast<T*>(event->release()));
|
||||
static mozilla::UniquePtr<T> Cast(ScopedEvent* event) {
|
||||
return mozilla::WrapUnique(static_cast<T*>(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<UserMessage> message);
|
||||
void AttachMessage(mozilla::UniquePtr<UserMessage> message);
|
||||
|
||||
template <typename T>
|
||||
T* GetMessage() {
|
||||
|
@ -156,12 +154,12 @@ class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event {
|
|||
uint64_t sequence_num_ = 0;
|
||||
std::vector<PortDescriptor> port_descriptors_;
|
||||
std::vector<PortName> ports_;
|
||||
std::unique_ptr<UserMessage> message_;
|
||||
mozilla::UniquePtr<UserMessage> 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);
|
||||
|
|
|
@ -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<UserMessageEvent>& a,
|
||||
const std::unique_ptr<UserMessageEvent>& b) {
|
||||
inline bool operator<(const mozilla::UniquePtr<UserMessageEvent>& a,
|
||||
const mozilla::UniquePtr<UserMessageEvent>& 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<UserMessageEvent>* message,
|
||||
void MessageQueue::GetNextMessage(mozilla::UniquePtr<UserMessageEvent>* message,
|
||||
MessageFilter* filter) {
|
||||
if (!HasNextMessage() || (filter && !filter->Match(*heap_[0]))) {
|
||||
message->reset();
|
||||
|
@ -58,15 +63,15 @@ void MessageQueue::GetNextMessage(std::unique_ptr<UserMessageEvent>* 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<UserMessageEvent> message,
|
||||
void MessageQueue::AcceptMessage(mozilla::UniquePtr<UserMessageEvent> message,
|
||||
bool* has_next_message) {
|
||||
// TODO: Handle sequence number roll-over.
|
||||
|
||||
|
@ -82,7 +87,7 @@ void MessageQueue::AcceptMessage(std::unique_ptr<UserMessageEvent> message,
|
|||
}
|
||||
|
||||
void MessageQueue::TakeAllMessages(
|
||||
std::vector<std::unique_ptr<UserMessageEvent>>* messages) {
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>>* messages) {
|
||||
*messages = std::move(heap_);
|
||||
total_queued_bytes_ = 0;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<UserMessageEvent>* message,
|
||||
void GetNextMessage(mozilla::UniquePtr<UserMessageEvent>* 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<UserMessageEvent> message,
|
||||
void AcceptMessage(mozilla::UniquePtr<UserMessageEvent> 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<std::unique_ptr<UserMessageEvent>>* messages);
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>>* 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<std::unique_ptr<UserMessageEvent>> heap_;
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>> heap_;
|
||||
uint64_t next_sequence_num_;
|
||||
bool signalable_ = true;
|
||||
size_t total_queued_bytes_ = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
|
||||
};
|
||||
|
||||
} // namespace ports
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
#include <ostream>
|
||||
#include <tuple>
|
||||
|
||||
#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<mojo::core::ports::PortName> {
|
||||
struct hash<mojo::core::ports::PortName> {
|
||||
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<mojo::core::ports::NodeName> {
|
||||
struct hash<mojo::core::ports::NodeName> {
|
||||
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 <vector>
|
||||
|
||||
#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<RandomNameGenerator>::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> port(new Port(kInitialSequenceNum, kInitialSequenceNum));
|
||||
RefPtr<Port> 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<UserData> user_data) {
|
||||
int Node::SetUserData(const PortRef& port_ref, RefPtr<UserData> 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<UserData>* user_data) {
|
||||
int Node::GetUserData(const PortRef& port_ref, RefPtr<UserData>* 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<std::unique_ptr<UserMessageEvent>> undelivered_messages;
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>> 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<ObserveClosureEvent>(
|
||||
mozilla::MakeUnique<ObserveClosureEvent>(
|
||||
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<UserMessageEvent>* message,
|
||||
mozilla::UniquePtr<UserMessageEvent>* 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<UserMessageReadAckEvent>(
|
||||
ack_event = mozilla::MakeUnique<UserMessageReadAckEvent>(
|
||||
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<UserMessageEvent> message) {
|
||||
mozilla::UniquePtr<UserMessageEvent> 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<UserMessageReadAckRequestEvent>(
|
||||
mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
|
||||
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<MergePortEvent>(destination_port_name, new_port_name,
|
||||
new_port_descriptor));
|
||||
mozilla::MakeUnique<MergePortEvent>(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<UserMessageEvent> message) {
|
||||
int Node::OnUserMessage(mozilla::UniquePtr<UserMessageEvent> 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<UserMessageEvent> message) {
|
|||
return OK;
|
||||
}
|
||||
|
||||
int Node::OnPortAccepted(std::unique_ptr<PortAcceptedEvent> event) {
|
||||
int Node::OnPortAccepted(mozilla::UniquePtr<PortAcceptedEvent> 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<PortAcceptedEvent> event) {
|
|||
return BeginProxying(port_ref);
|
||||
}
|
||||
|
||||
int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) {
|
||||
int Node::OnObserveProxy(mozilla::UniquePtr<ObserveProxyEvent> 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<ObserveProxyEvent> 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<ObserveProxyEvent> event) {
|
|||
event->proxy_target_node_name(),
|
||||
event->proxy_target_port_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);
|
||||
peer_changed = true;
|
||||
DVLOG(2) << "Forwarding ObserveProxyAck from " << event->port_name()
|
||||
|
@ -660,10 +613,10 @@ int Node::OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event) {
|
|||
<< "@" << event->proxy_node_name();
|
||||
|
||||
port->send_on_proxy_removal =
|
||||
std::make_unique<std::pair<NodeName, ScopedEvent>>(
|
||||
mozilla::MakeUnique<std::pair<NodeName, ScopedEvent>>(
|
||||
event->proxy_node_name(),
|
||||
std::make_unique<ObserveProxyAckEvent>(event->proxy_port_name(),
|
||||
kInvalidSequenceNum));
|
||||
mozilla::MakeUnique<ObserveProxyAckEvent>(
|
||||
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<ObserveProxyEvent> event) {
|
|||
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_
|
||||
<< " (last_sequence_num=" << event->last_sequence_num() << ")";
|
||||
|
||||
|
@ -725,7 +678,7 @@ int Node::OnObserveProxyAck(std::unique_ptr<ObserveProxyAckEvent> event) {
|
|||
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.
|
||||
PortRef port_ref;
|
||||
if (GetPort(event->port_name(), &port_ref) != OK) return OK;
|
||||
|
@ -799,7 +752,7 @@ int Node::OnObserveClosure(std::unique_ptr<ObserveClosureEvent> event) {
|
|||
return OK;
|
||||
}
|
||||
|
||||
int Node::OnMergePort(std::unique_ptr<MergePortEvent> event) {
|
||||
int Node::OnMergePort(mozilla::UniquePtr<MergePortEvent> event) {
|
||||
PortRef port_ref;
|
||||
GetPort(event->port_name(), &port_ref);
|
||||
|
||||
|
@ -835,7 +788,7 @@ int Node::OnMergePort(std::unique_ptr<MergePortEvent> event) {
|
|||
}
|
||||
|
||||
int Node::OnUserMessageReadAckRequest(
|
||||
std::unique_ptr<UserMessageReadAckRequestEvent> event) {
|
||||
mozilla::UniquePtr<UserMessageReadAckRequestEvent> 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> event_to_send;
|
||||
mozilla::UniquePtr<Event> 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<UserMessageReadAckEvent>(
|
||||
event_to_send = mozilla::MakeUnique<UserMessageReadAckEvent>(
|
||||
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<UserMessageReadAckEvent> event) {
|
||||
int Node::OnUserMessageReadAck(
|
||||
mozilla::UniquePtr<UserMessageReadAckEvent> event) {
|
||||
PortRef port_ref;
|
||||
GetPort(event->port_name(), &port_ref);
|
||||
|
||||
|
@ -929,7 +883,7 @@ int Node::OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> 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<UserMessageReadAckRequestEvent>(
|
||||
ack_request_event = mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
|
||||
port->peer_port_name, port->last_sequence_num_acknowledged +
|
||||
port->sequence_num_acknowledge_interval);
|
||||
}
|
||||
|
@ -942,9 +896,9 @@ int Node::OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> event) {
|
|||
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();
|
||||
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> port) {
|
|||
|
||||
void Node::ErasePort(const PortName& port_name) {
|
||||
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);
|
||||
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<std::unique_ptr<UserMessageEvent>> messages;
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>> 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<UserMessageEvent>* message) {
|
||||
std::unique_ptr<UserMessageEvent>& m = *message;
|
||||
int Node::SendUserMessageInternal(
|
||||
const PortRef& port_ref, mozilla::UniquePtr<UserMessageEvent>* message) {
|
||||
mozilla::UniquePtr<UserMessageEvent>& 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<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* 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<ObserveClosureEvent>(
|
||||
closure_event = mozilla::MakeUnique<ObserveClosureEvent>(
|
||||
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> port =
|
||||
base::MakeRefCounted<Port>(port_descriptor.next_sequence_num_to_send,
|
||||
port_descriptor.next_sequence_num_to_receive);
|
||||
RefPtr<Port> port =
|
||||
mozilla::MakeRefPtr<Port>(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<PortAcceptedEvent>(port_descriptor.referring_port_name));
|
||||
delegate_->ForwardEvent(port_descriptor.referring_node_name,
|
||||
mozilla::MakeUnique<PortAcceptedEvent>(
|
||||
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<PortRef, 4> attached_port_refs;
|
||||
base::StackVector<const PortRef*, 5> 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<PortRef, 4> attached_port_refs;
|
||||
AutoTArray<const PortRef*, 5> 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<ObserveClosureEvent>(
|
||||
closure_event = mozilla::MakeUnique<ObserveClosureEvent>(
|
||||
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<UserMessageEvent> message;
|
||||
mozilla::UniquePtr<UserMessageEvent> 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<ObserveProxyEvent>(
|
||||
mozilla::MakeUnique<ObserveProxyEvent>(
|
||||
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<PortRef> ports_to_notify;
|
||||
std::vector<PortName> dead_proxies_to_broadcast;
|
||||
std::vector<std::unique_ptr<UserMessageEvent>> undelivered_messages;
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>> 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<std::unique_ptr<UserMessageEvent>> messages;
|
||||
std::vector<mozilla::UniquePtr<UserMessageEvent>> 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<ObserveProxyEvent>(
|
||||
delegate_->BroadcastEvent(mozilla::MakeUnique<ObserveProxyEvent>(
|
||||
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<Port>(local_port)));
|
||||
local_port_name, PortRef(local_port_name, RefPtr<Port>{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<Port>(port1)));
|
||||
peer1_ports.emplace(port0_name,
|
||||
PortRef(port0_name, base::WrapRefCounted<Port>(port0)));
|
||||
peer0_ports.emplace(port1_name, PortRef(port1_name, RefPtr<Port>{port1}));
|
||||
peer1_ports.emplace(port0_name, PortRef(port0_name, RefPtr<Port>{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<UserMessageReadAckRequestEvent>(
|
||||
ack_request_event = mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
|
||||
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<UserMessageReadAckRequestEvent>(
|
||||
ack_request_event = mozilla::MakeUnique<UserMessageReadAckRequestEvent>(
|
||||
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<UserMessageReadAckEvent>(
|
||||
ack_event = mozilla::MakeUnique<UserMessageReadAckEvent>(
|
||||
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
|
||||
|
||||
|
|
|
@ -11,16 +11,13 @@
|
|||
#include <queue>
|
||||
#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/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<UserData> user_data);
|
||||
int GetUserData(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, RefPtr<UserData>* 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<UserMessageEvent>* message,
|
||||
mozilla::UniquePtr<UserMessageEvent>* 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<UserMessageEvent> message);
|
||||
mozilla::UniquePtr<UserMessageEvent> 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<UserMessageEvent> message);
|
||||
int OnPortAccepted(std::unique_ptr<PortAcceptedEvent> event);
|
||||
int OnObserveProxy(std::unique_ptr<ObserveProxyEvent> event);
|
||||
int OnObserveProxyAck(std::unique_ptr<ObserveProxyAckEvent> event);
|
||||
int OnObserveClosure(std::unique_ptr<ObserveClosureEvent> event);
|
||||
int OnMergePort(std::unique_ptr<MergePortEvent> event);
|
||||
int OnUserMessage(mozilla::UniquePtr<UserMessageEvent> message);
|
||||
int OnPortAccepted(mozilla::UniquePtr<PortAcceptedEvent> event);
|
||||
int OnObserveProxy(mozilla::UniquePtr<ObserveProxyEvent> event);
|
||||
int OnObserveProxyAck(mozilla::UniquePtr<ObserveProxyAckEvent> event);
|
||||
int OnObserveClosure(mozilla::UniquePtr<ObserveClosureEvent> event);
|
||||
int OnMergePort(mozilla::UniquePtr<MergePortEvent> event);
|
||||
int OnUserMessageReadAckRequest(
|
||||
std::unique_ptr<UserMessageReadAckRequestEvent> event);
|
||||
int OnUserMessageReadAck(std::unique_ptr<UserMessageReadAckEvent> event);
|
||||
mozilla::UniquePtr<UserMessageReadAckRequestEvent> 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);
|
||||
|
||||
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,
|
||||
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<LocalPortName, scoped_refptr<Port>> ports_;
|
||||
mozilla::Mutex ports_lock_{"Ports Lock"};
|
||||
std::unordered_map<LocalPortName, RefPtr<Port>> 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<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 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<NodeName, PeerPortMap> peer_port_maps_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Node);
|
||||
};
|
||||
|
||||
} // namespace ports
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
#include <utility>
|
||||
#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/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<Port> {
|
||||
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<Port> {
|
|||
// 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<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
|
||||
// stash an observer interface which can be notified about various Port state
|
||||
// changes.
|
||||
scoped_refptr<UserData> user_data;
|
||||
RefPtr<UserData> 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> {
|
|||
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<Port>;
|
||||
friend class PortLocker;
|
||||
|
||||
~Port();
|
||||
|
||||
base::Lock lock_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Port);
|
||||
mozilla::Mutex lock_{"Port State"};
|
||||
};
|
||||
|
||||
} // namespace ports
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -14,7 +14,7 @@ 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)) {}
|
||||
|
||||
PortRef::PortRef(const PortRef& other) = default;
|
||||
|
|
|
@ -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> port);
|
||||
PortRef(const PortName& name, RefPtr<Port> 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> port_;
|
||||
RefPtr<Port> port_;
|
||||
};
|
||||
|
||||
} // namespace ports
|
||||
|
|
|
@ -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<UserData> {
|
||||
protected:
|
||||
friend class base::RefCountedThreadSafe<UserData>;
|
||||
class UserData {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UserData);
|
||||
|
||||
protected:
|
||||
virtual ~UserData() = default;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
#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
|
||||
|
|
Загрузка…
Ссылка в новой задаче