Commit 6f2a3a00 authored by Chris Hamilton's avatar Chris Hamilton Committed by Commit Bot

[PM] Create ExecutionContextAttachedData adapter.

This creates a helper that allows NodeAttachedData on abstract
ExecutionContext node wrappers.

BUG=1080672

Change-Id: I8587841824bcf65a91eff85ab259f4b7321e0016
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2506231
Commit-Queue: Chris Hamilton <chrisha@chromium.org>
Reviewed-by: default avatarJoe Mason <joenotcharles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821894}
parent b4795913
...@@ -91,6 +91,7 @@ static_library("performance_manager") { ...@@ -91,6 +91,7 @@ static_library("performance_manager") {
"public/decorators/page_load_tracker_decorator_helper.h", "public/decorators/page_load_tracker_decorator_helper.h",
"public/decorators/tab_properties_decorator.h", "public/decorators/tab_properties_decorator.h",
"public/execution_context/execution_context.h", "public/execution_context/execution_context.h",
"public/execution_context/execution_context_attached_data.h",
"public/execution_context/execution_context_registry.h", "public/execution_context/execution_context_registry.h",
"public/execution_context_priority/boosting_vote_aggregator.h", "public/execution_context_priority/boosting_vote_aggregator.h",
"public/execution_context_priority/execution_context_priority.h", "public/execution_context_priority/execution_context_priority.h",
...@@ -211,6 +212,7 @@ source_set("unit_tests") { ...@@ -211,6 +212,7 @@ source_set("unit_tests") {
"decorators/page_live_state_decorator_unittest.cc", "decorators/page_live_state_decorator_unittest.cc",
"decorators/page_load_tracker_decorator_unittest.cc", "decorators/page_load_tracker_decorator_unittest.cc",
"decorators/tab_properties_decorator_unittest.cc", "decorators/tab_properties_decorator_unittest.cc",
"execution_context/execution_context_attached_data_unittest.cc",
"execution_context/execution_context_registry_impl_unittest.cc", "execution_context/execution_context_registry_impl_unittest.cc",
"execution_context_priority/boosting_vote_aggregator_unittest.cc", "execution_context_priority/boosting_vote_aggregator_unittest.cc",
"execution_context_priority/execution_context_priority_unittest.cc", "execution_context_priority/execution_context_priority_unittest.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/performance_manager/public/execution_context/execution_context_attached_data.h"
#include "components/performance_manager/execution_context/execution_context_registry_impl.h"
#include "components/performance_manager/test_support/graph_test_harness.h"
#include "components/performance_manager/test_support/mock_graphs.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace performance_manager {
namespace execution_context {
namespace {
class FakeData : public ExecutionContextAttachedData<FakeData> {
public:
FakeData() = default;
explicit FakeData(const ExecutionContext* ec) {}
~FakeData() override = default;
};
class ExecutionContextAttachedDataTest : public GraphTestHarness {
public:
using Super = GraphTestHarness;
ExecutionContextAttachedDataTest() = default;
ExecutionContextAttachedDataTest(const ExecutionContextAttachedDataTest&) =
delete;
ExecutionContextAttachedDataTest& operator=(
const ExecutionContextAttachedDataTest&) = delete;
~ExecutionContextAttachedDataTest() override = default;
void SetUp() override {
Super::SetUp();
graph()->PassToGraph(std::make_unique<ExecutionContextRegistryImpl>());
registry_ = GraphRegisteredImpl<ExecutionContextRegistryImpl>::GetFromGraph(
graph());
ASSERT_TRUE(registry_);
}
protected:
ExecutionContextRegistryImpl* registry_ = nullptr;
};
} // namespace
TEST_F(ExecutionContextAttachedDataTest, AdapterWorks) {
MockMultiplePagesAndWorkersWithMultipleProcessesGraph mock_graph(graph());
auto* ec1 =
registry_->GetExecutionContextForFrameNode(mock_graph.frame.get());
auto* ec2 =
registry_->GetExecutionContextForWorkerNode(mock_graph.worker.get());
EXPECT_FALSE(FakeData::Destroy(ec1));
FakeData* fd1 = FakeData::Get(ec1);
EXPECT_FALSE(fd1);
fd1 = FakeData::GetOrCreate(ec1);
EXPECT_TRUE(fd1);
EXPECT_EQ(fd1, FakeData::Get(ec1));
EXPECT_TRUE(FakeData::Destroy(ec1));
EXPECT_FALSE(FakeData::Get(ec1));
EXPECT_FALSE(FakeData::Destroy(ec2));
FakeData* fd2 = FakeData::Get(ec2);
EXPECT_FALSE(fd2);
fd2 = FakeData::GetOrCreate(ec2);
EXPECT_TRUE(fd2);
EXPECT_EQ(fd2, FakeData::Get(ec2));
EXPECT_TRUE(FakeData::Destroy(ec2));
EXPECT_FALSE(FakeData::Get(ec2));
}
} // namespace execution_context
} // namespace performance_manager
// Copyright 2020 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.
#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_EXECUTION_CONTEXT_EXECUTION_CONTEXT_ATTACHED_DATA_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_EXECUTION_CONTEXT_EXECUTION_CONTEXT_ATTACHED_DATA_H_
#include "components/performance_manager/public/execution_context/execution_context.h"
#include "components/performance_manager/public/execution_context/execution_context_registry.h"
#include "components/performance_manager/public/graph/frame_node.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/graph/node_attached_data.h"
#include "components/performance_manager/public/graph/worker_node.h"
namespace performance_manager {
namespace execution_context {
// An adapter that can be used to associate NodeAttachedData with all node
// types that represent execution contexts. Under the hood this wraps
// ExternalNodeAttachedDataImpl for each of the underlying node types.
// It is expected that UserDataType have a constructor with the signature
// "UserDataType(const ExecutionContext*)".
template <typename UserDataType>
class ExecutionContextAttachedData {
public:
ExecutionContextAttachedData() = default;
ExecutionContextAttachedData(const ExecutionContextAttachedData&) = delete;
ExecutionContextAttachedData& operator=(const ExecutionContextAttachedData&) =
delete;
virtual ~ExecutionContextAttachedData() = default;
// Gets the user data for the given |node|, creating it if it doesn't yet
// exist.
static UserDataType* GetOrCreate(const ExecutionContext* ec) {
return Dispatch<GetOrCreateFunctor>(ec);
}
// Gets the user data for the given |node|, returning nullptr if it doesn't
// exist.
static UserDataType* Get(const ExecutionContext* ec) {
return Dispatch<GetFunctor>(ec);
}
// Destroys the user data associated with the given node, returning true
// on success or false if the user data did not exist to begin with.
static bool Destroy(const ExecutionContext* ec) {
return Dispatch<DestroyFunctor>(ec);
}
private:
// A small adapter for UserDataType that makes it compatible with
// underlying node types.
class UserDataWrapper : public ExternalNodeAttachedDataImpl<UserDataWrapper>,
public UserDataType {
public:
explicit UserDataWrapper(const FrameNode* frame_node)
: UserDataType(
ExecutionContextRegistry::GetFromGraph(frame_node->GetGraph())
->GetExecutionContextForFrameNode(frame_node)) {}
explicit UserDataWrapper(const WorkerNode* worker_node)
: UserDataType(
ExecutionContextRegistry::GetFromGraph(worker_node->GetGraph())
->GetExecutionContextForWorkerNode(worker_node)) {}
};
// Helpers for dynamic dispatch to various functions based on the underlying
// node type.
struct GetOrCreateFunctor {
using ReturnType = UserDataType*;
template <typename NodeType>
static UserDataType* Do(const NodeType* node) {
return ExternalNodeAttachedDataImpl<UserDataWrapper>::GetOrCreate(node);
}
};
struct GetFunctor {
using ReturnType = UserDataType*;
template <typename NodeType>
static UserDataType* Do(const NodeType* node) {
return ExternalNodeAttachedDataImpl<UserDataWrapper>::Get(node);
}
};
struct DestroyFunctor {
using ReturnType = bool;
template <typename NodeType>
static bool Do(const NodeType* node) {
return ExternalNodeAttachedDataImpl<UserDataWrapper>::Destroy(node);
}
};
// Helper for dynamic dispatching based on underlying node type.
template <typename Functor>
static typename Functor::ReturnType Dispatch(const ExecutionContext* ec) {
switch (ec->GetType()) {
case ExecutionContextType::kFrameNode:
return Functor::Do(ec->GetFrameNode());
case ExecutionContextType::kWorkerNode:
return Functor::Do(ec->GetWorkerNode());
}
}
};
} // namespace execution_context
} // namespace performance_manager
#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_EXECUTION_CONTEXT_EXECUTION_CONTEXT_ATTACHED_DATA_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment