base: Add WeakRunner
This is a wrapper around a TaskRunner that allows safely capturing
`this`.
It is going to be used in future commits in TracingServiceImpl. It might
be also nice to use in HeapprofdProducer.
Change-Id: I526128c7f0f91d729b17a7c7c92f1b0e07a52da6
diff --git a/Android.bp b/Android.bp
index 3792d85..12e2e61 100644
--- a/Android.bp
+++ b/Android.bp
@@ -10898,6 +10898,7 @@
"src/base/virtual_destructors.cc",
"src/base/waitable_event.cc",
"src/base/watchdog_posix.cc",
+ "src/base/weak_runner.cc",
],
}
diff --git a/BUILD b/BUILD
index 5384b7b..fd521e9 100644
--- a/BUILD
+++ b/BUILD
@@ -1278,6 +1278,8 @@
"src/base/virtual_destructors.cc",
"src/base/waitable_event.cc",
"src/base/watchdog_posix.cc",
+ "src/base/weak_runner.cc",
+ "src/base/weak_runner.h",
],
hdrs = [
":include_perfetto_base_base",
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index ace0ac6..a5edbac 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -60,6 +60,8 @@
"virtual_destructors.cc",
"waitable_event.cc",
"watchdog_posix.cc",
+ "weak_runner.cc",
+ "weak_runner.h",
]
if (!is_nacl) {
diff --git a/src/base/weak_runner.cc b/src/base/weak_runner.cc
new file mode 100644
index 0000000..ba63b67
--- /dev/null
+++ b/src/base/weak_runner.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/base/weak_runner.h"
+
+#include "perfetto/base/task_runner.h"
+
+namespace perfetto::base {
+
+WeakRunner::WeakRunner(base::TaskRunner* task_runner)
+ : task_runner_(task_runner), destroyed_(std::make_shared<bool>(false)) {}
+
+WeakRunner::~WeakRunner() {
+ *destroyed_ = true;
+}
+
+void WeakRunner::PostTask(std::function<void()> f) const {
+ task_runner_->PostTask([destroyed = destroyed_, f = std::move(f)]() {
+ if (*destroyed) {
+ return;
+ }
+ f();
+ });
+}
+
+void WeakRunner::PostDelayedTask(std::function<void()> f,
+ uint32_t delay_ms) const {
+ task_runner_->PostDelayedTask(
+ [destroyed = destroyed_, f = std::move(f)]() {
+ if (*destroyed) {
+ return;
+ }
+ f();
+ },
+ delay_ms);
+}
+
+} // namespace perfetto::base
diff --git a/src/base/weak_runner.h b/src/base/weak_runner.h
new file mode 100644
index 0000000..e9959a3
--- /dev/null
+++ b/src/base/weak_runner.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_BASE_WEAK_RUNNER_H_
+#define SRC_BASE_WEAK_RUNNER_H_
+
+#include <functional>
+#include <memory>
+
+namespace perfetto::base {
+
+class TaskRunner;
+
+// This is a wrapper around a `base::TaskRunner*`. It is intended to be used by
+// classes that want to post tasks on themselves. When the object is destroyed,
+// all posted tasks become noops.
+//
+// A class that embeds a WeakRunner can safely capture `this` on the posted
+// tasks.
+class WeakRunner {
+ public:
+ explicit WeakRunner(base::TaskRunner* task_runner);
+ ~WeakRunner();
+ base::TaskRunner* task_runner() const { return task_runner_; }
+
+ // Schedules `f` for immediate execution. `f` will not be executed is `*this`
+ // is destroyed.
+ //
+ // Can be called from any thread, but the caller needs to make sure that
+ // `*this` is alive while `PostTask` is running: this is not obvious when
+ // multiple threads are involved.
+ void PostTask(std::function<void()> f) const;
+
+ // Schedules `f` for execution after |delay_ms|.
+ // Can be called from any thread, but the caller needs to make sure that
+ // `*this` is alive while `PostDelayedTask` is running: this is not obvious
+ // when multiple threads are involved.
+ void PostDelayedTask(std::function<void()> f, uint32_t delay_ms) const;
+
+ private:
+ base::TaskRunner* const task_runner_;
+ std::shared_ptr<bool> destroyed_;
+};
+
+} // namespace perfetto::base
+
+#endif // SRC_BASE_WEAK_RUNNER_H_