Commit 846ebc40 authored by Stephen Nusko's avatar Stephen Nusko Committed by Commit Bot

Implement Add/Remove FileDescriptorWatch for the PerfettoTaskRunner

This is needed in a future CL to connect via the IPC mechanism used by
the system Perfetto service on Android.

Bug: 966047
Change-Id: I0521d9e91cc6d3332607be747743a2ab590255ed
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1624817
Commit-Queue: Stephen Nusko <nuskos@chromium.org>
Auto-Submit: Stephen Nusko <nuskos@chromium.org>
Reviewed-by: default avatarEric Seckler <eseckler@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#672063}
parent 5088ee0e
...@@ -73,6 +73,17 @@ class ThreadedPerfettoService : public mojom::TracingSessionClient { ...@@ -73,6 +73,17 @@ class ThreadedPerfettoService : public mojom::TracingSessionClient {
wait_for_destruction.Run(); wait_for_destruction.Run();
} }
{
base::RunLoop wait_for_destruction;
task_runner_->PostTaskAndReply(
FROM_HERE,
base::BindOnce(
[](std::unique_ptr<PerfettoService> service) { service.reset(); },
std::move(perfetto_service_)),
wait_for_destruction.QuitClosure());
wait_for_destruction.Run();
}
{ {
base::RunLoop wait_for_destruction; base::RunLoop wait_for_destruction;
PerfettoTracedProcess::GetTaskRunner() PerfettoTracedProcess::GetTaskRunner()
......
...@@ -258,10 +258,19 @@ MockProducer::MockProducer(const std::string& producer_name, ...@@ -258,10 +258,19 @@ MockProducer::MockProducer(const std::string& producer_name,
base::OnceClosure on_datasource_registered, base::OnceClosure on_datasource_registered,
base::OnceClosure on_tracing_started, base::OnceClosure on_tracing_started,
size_t num_packets) { size_t num_packets) {
data_source_ = // Construct MockProducerClient before TestDataSource to avoid a race.
std::make_unique<TestDataSource>(data_source_name, num_packets); //
// TestDataSource calls AddDataSource on the global PerfettoTracedProcess,
// which PostTasks to the threadpool in the task it will access the
// |producer_client_| pointer that the PerfettoTracedProcess owns. However in
// the constructor for MockProducerClient we will set the |producer_client_|
// from the real client to the mock, however this is done on a different
// sequence and thus we have a race. By setting the pointer before we
// construct the data source the TestDataSource can not race.
producer_client_ = std::make_unique<MockProducerClient>( producer_client_ = std::make_unique<MockProducerClient>(
/* num_data_sources = */ 1, std::move(on_tracing_started)); /* num_data_sources = */ 1, std::move(on_tracing_started));
data_source_ =
std::make_unique<TestDataSource>(data_source_name, num_packets);
producer_host_ = std::make_unique<MockProducerHost>( producer_host_ = std::make_unique<MockProducerHost>(
producer_name, data_source_name, service, producer_client_.get(), producer_name, data_source_name, service, producer_client_.get(),
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/stl_util.h"
#include "base/task/common/checked_lock_impl.h" #include "base/task/common/checked_lock_impl.h"
#include "base/task/common/scoped_defer_task_posting.h" #include "base/task/common/scoped_defer_task_posting.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
...@@ -24,7 +25,12 @@ PerfettoTaskRunner::PerfettoTaskRunner( ...@@ -24,7 +25,12 @@ PerfettoTaskRunner::PerfettoTaskRunner(
scoped_refptr<base::SequencedTaskRunner> task_runner) scoped_refptr<base::SequencedTaskRunner> task_runner)
: task_runner_(std::move(task_runner)) {} : task_runner_(std::move(task_runner)) {}
PerfettoTaskRunner::~PerfettoTaskRunner() = default; PerfettoTaskRunner::~PerfettoTaskRunner() {
DCHECK(GetOrCreateTaskRunner()->RunsTasksInCurrentSequence());
#if defined(OS_ANDROID)
fd_controllers_.clear();
#endif // defined(OS_ANDROID)
}
void PerfettoTaskRunner::PostTask(std::function<void()> task) { void PerfettoTaskRunner::PostTask(std::function<void()> task) {
base::ScopedDeferTaskPosting::PostOrDefer( base::ScopedDeferTaskPosting::PostOrDefer(
...@@ -70,12 +76,29 @@ bool PerfettoTaskRunner::RunsTasksOnCurrentThread() const { ...@@ -70,12 +76,29 @@ bool PerfettoTaskRunner::RunsTasksOnCurrentThread() const {
return task_runner_->RunsTasksInCurrentSequence(); return task_runner_->RunsTasksInCurrentSequence();
} }
void PerfettoTaskRunner::AddFileDescriptorWatch(int fd, std::function<void()>) { void PerfettoTaskRunner::AddFileDescriptorWatch(
int fd,
std::function<void()> callback) {
#if !defined(OS_ANDROID)
NOTREACHED(); NOTREACHED();
#else
DCHECK(GetOrCreateTaskRunner()->RunsTasksInCurrentSequence());
DCHECK(!base::Contains(fd_controllers_, fd));
fd_controllers_[fd] = base::FileDescriptorWatcher::WatchReadable(
fd,
base::BindRepeating([](std::function<void()> callback) { callback(); },
std::move(callback)));
#endif // !defined(OS_ANDROID)
} }
void PerfettoTaskRunner::RemoveFileDescriptorWatch(int fd) { void PerfettoTaskRunner::RemoveFileDescriptorWatch(int fd) {
#if !defined(OS_ANDROID)
NOTREACHED(); NOTREACHED();
#else
DCHECK(GetOrCreateTaskRunner()->RunsTasksInCurrentSequence());
DCHECK(base::Contains(fd_controllers_, fd));
fd_controllers_.erase(fd);
#endif // !defined(OS_ANDROID)
} }
void PerfettoTaskRunner::ResetTaskRunnerForTesting( void PerfettoTaskRunner::ResetTaskRunnerForTesting(
......
...@@ -12,9 +12,17 @@ ...@@ -12,9 +12,17 @@
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "build/build_config.h"
#include "services/tracing/public/mojom/perfetto_service.mojom.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h"
#include "third_party/perfetto/include/perfetto/base/task_runner.h" #include "third_party/perfetto/include/perfetto/base/task_runner.h"
#if defined(OS_ANDROID)
#include <map>
// Needed for base::FileDescriptorWatcher::Controller and for implementing
// AddFileDescriptorWatch & RemoveFileDescriptorWatch on Android.
#include "base/files/file_descriptor_watcher_posix.h"
#endif // defined(OS_ANDROID)
namespace tracing { namespace tracing {
// This wraps a base::TaskRunner implementation to be able // This wraps a base::TaskRunner implementation to be able
...@@ -40,7 +48,7 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTaskRunner ...@@ -40,7 +48,7 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTaskRunner
scoped_refptr<base::SequencedTaskRunner> GetOrCreateTaskRunner(); scoped_refptr<base::SequencedTaskRunner> GetOrCreateTaskRunner();
bool HasTaskRunner() const { return !!task_runner_; } bool HasTaskRunner() const { return !!task_runner_; }
// Not used in Chrome. // These are only used on Android when talking to the system Perfetto service.
void AddFileDescriptorWatch(int fd, std::function<void()>) override; void AddFileDescriptorWatch(int fd, std::function<void()>) override;
void RemoveFileDescriptorWatch(int fd) override; void RemoveFileDescriptorWatch(int fd) override;
...@@ -54,6 +62,10 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTaskRunner ...@@ -54,6 +62,10 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTaskRunner
void OnDeferredTasksDrainTimer(); void OnDeferredTasksDrainTimer();
scoped_refptr<base::SequencedTaskRunner> task_runner_; scoped_refptr<base::SequencedTaskRunner> task_runner_;
#if defined(OS_ANDROID)
std::map<int, std::unique_ptr<base::FileDescriptorWatcher::Controller>>
fd_controllers_;
#endif // defined(OS_ANDROID)
DISALLOW_COPY_AND_ASSIGN(PerfettoTaskRunner); DISALLOW_COPY_AND_ASSIGN(PerfettoTaskRunner);
}; };
......
...@@ -91,7 +91,8 @@ class PosterThread : public base::SimpleThread { ...@@ -91,7 +91,8 @@ class PosterThread : public base::SimpleThread {
class PerfettoTaskRunnerTest : public testing::Test { class PerfettoTaskRunnerTest : public testing::Test {
public: public:
void SetUp() override { void SetUp() override {
task_runner_ = std::make_unique<PerfettoTaskRunner>(CreateNewTaskrunner()); sequenced_task_runner_ = CreateNewTaskrunner();
task_runner_ = std::make_unique<PerfettoTaskRunner>(sequenced_task_runner_);
} }
scoped_refptr<base::SequencedTaskRunner> CreateNewTaskrunner() { scoped_refptr<base::SequencedTaskRunner> CreateNewTaskrunner() {
...@@ -105,15 +106,18 @@ class PerfettoTaskRunnerTest : public testing::Test { ...@@ -105,15 +106,18 @@ class PerfettoTaskRunnerTest : public testing::Test {
number_of_sequences, expected_tasks, std::move(on_complete)); number_of_sequences, expected_tasks, std::move(on_complete));
} }
void TearDown() override {} void TearDown() override {
sequenced_task_runner_->DeleteSoon(FROM_HERE, std::move(task_runner_));
}
PerfettoTaskRunner* task_runner() { return task_runner_.get(); } PerfettoTaskRunner* task_runner() { return task_runner_.get(); }
TaskDestination* destination() { return task_destination_.get(); } TaskDestination* destination() { return task_destination_.get(); }
private: private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
std::unique_ptr<PerfettoTaskRunner> task_runner_; std::unique_ptr<PerfettoTaskRunner> task_runner_;
std::unique_ptr<TaskDestination> task_destination_; std::unique_ptr<TaskDestination> task_destination_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
}; };
TEST_F(PerfettoTaskRunnerTest, SequentialTasks) { TEST_F(PerfettoTaskRunnerTest, SequentialTasks) {
......
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