Introduce `TaskRunnerAffineWeakPtrFactory` to generate `TaskRunnerAffineWeakPtr`s (#18346)
diff --git a/fml/memory/weak_ptr.h b/fml/memory/weak_ptr.h
index 95fc964..1f72930 100644
--- a/fml/memory/weak_ptr.h
+++ b/fml/memory/weak_ptr.h
@@ -30,17 +30,18 @@
template <typename T>
class WeakPtrFactory;
-// Class for "weak pointers" that can be invalidated. Valid weak pointers can
-// only originate from a |WeakPtrFactory| (see below), though weak pointers are
-// copyable and movable.
+// Class for "weak pointers" that can be invalidated. Valid weak pointers
+// can only originate from a |WeakPtrFactory| (see below), though weak
+// pointers are copyable and movable.
//
-// Weak pointers are not in general thread-safe. They may only be *used* on a
-// single thread, namely the same thread as the "originating" |WeakPtrFactory|
-// (which can invalidate the weak pointers that it generates).
+// Weak pointers are not in general thread-safe. They may only be *used* on
+// a single thread, namely the same thread as the "originating"
+// |WeakPtrFactory| (which can invalidate the weak pointers that it
+// generates).
//
// However, weak pointers may be passed to other threads, reset on other
-// threads, or destroyed on other threads. They may also be reassigned on other
-// threads (in which case they should then only be used on the thread
+// threads, or destroyed on other threads. They may also be reassigned on
+// other threads (in which case they should then only be used on the thread
// corresponding to the new "originating" |WeakPtrFactory|).
template <typename T>
class WeakPtr {
@@ -117,9 +118,6 @@
explicit WeakPtr(T* ptr, fml::RefPtr<fml::internal::WeakPtrFlag>&& flag)
: ptr_(ptr), flag_(std::move(flag)) {}
- T* ptr_;
- fml::RefPtr<fml::internal::WeakPtrFlag> flag_;
-
virtual void CheckThreadSafety() const {
FML_DCHECK_CREATION_THREAD_IS_CURRENT(checker_.checker);
}
@@ -134,12 +132,17 @@
fml::RefPtr<fml::internal::WeakPtrFlag>&& flag,
DebugThreadChecker checker)
: ptr_(ptr), flag_(std::move(flag)), checker_(checker) {}
-
+ T* ptr_;
+ fml::RefPtr<fml::internal::WeakPtrFlag> flag_;
DebugThreadChecker checker_;
// Copy/move construction/assignment supported.
};
+// Forward declaration, so |TaskRunnerAffineWeakPtr<T>| can friend it.
+template <typename T>
+class TaskRunnerAffineWeakPtrFactory;
+
// A weak pointer that can be used in different threads as long as
// the threads are belong to the same |TaskRunner|.
//
@@ -153,14 +156,13 @@
template <typename U>
TaskRunnerAffineWeakPtr(const TaskRunnerAffineWeakPtr<U>& r)
- : WeakPtr<T>(static_cast<T*>(r.ptr_), r.flag_), checker_(r.checker_) {}
+ : WeakPtr<T>(r), checker_(r.checker_) {}
TaskRunnerAffineWeakPtr(TaskRunnerAffineWeakPtr<T>&& r) = default;
template <typename U>
TaskRunnerAffineWeakPtr(TaskRunnerAffineWeakPtr<U>&& r)
- : WeakPtr<T>(static_cast<T*>(r.ptr_), std::move(r.flag_)),
- checker_(r.checker_) {}
+ : WeakPtr<T>(r), checker_(r.checker_) {}
~TaskRunnerAffineWeakPtr() = default;
@@ -176,7 +178,9 @@
}
private:
- friend class WeakPtrFactory<T>;
+ template <typename U>
+ friend class TaskRunnerAffineWeakPtr;
+ friend class TaskRunnerAffineWeakPtrFactory<T>;
explicit TaskRunnerAffineWeakPtr(
T* ptr,
@@ -248,14 +252,7 @@
return WeakPtr<T>(ptr_, flag_.Clone(), checker_);
}
- // Gets a new weak pointer, which will be valid until either
- // |InvalidateWeakPtrs()| is called or this object is destroyed.
- TaskRunnerAffineWeakPtr<T> GetTaskRunnerAffineWeakPtr() const {
- return TaskRunnerAffineWeakPtr<T>(ptr_, flag_.Clone(),
- task_runner_checker_);
- }
-
- protected:
+ private:
// Note: See weak_ptr_internal.h for an explanation of why we store the
// pointer here, instead of in the "flag".
T* const ptr_;
@@ -265,13 +262,47 @@
FML_DCHECK_CREATION_THREAD_IS_CURRENT(checker_.checker);
}
- private:
DebugThreadChecker checker_;
- DebugTaskRunnerChecker task_runner_checker_;
FML_DISALLOW_COPY_AND_ASSIGN(WeakPtrFactory);
};
+// A type of |WeakPtrFactory| that produces |TaskRunnerAffineWeakPtr| instead of
+// |WeakPtr|.
+template <typename T>
+class TaskRunnerAffineWeakPtrFactory {
+ public:
+ explicit TaskRunnerAffineWeakPtrFactory(T* ptr)
+ : ptr_(ptr), flag_(fml::MakeRefCounted<fml::internal::WeakPtrFlag>()) {
+ FML_DCHECK(ptr_);
+ }
+
+ ~TaskRunnerAffineWeakPtrFactory() {
+ CheckThreadSafety();
+ flag_->Invalidate();
+ }
+
+ // Gets a new weak pointer, which will be valid until either
+ // |InvalidateWeakPtrs()| is called or this object is destroyed.
+ TaskRunnerAffineWeakPtr<T> GetWeakPtr() const {
+ return TaskRunnerAffineWeakPtr<T>(ptr_, flag_.Clone(), checker_);
+ }
+
+ private:
+ // Note: See weak_ptr_internal.h for an explanation of why we store the
+ // pointer here, instead of in the "flag".
+ T* const ptr_;
+ fml::RefPtr<fml::internal::WeakPtrFlag> flag_;
+
+ void CheckThreadSafety() const {
+ FML_DCHECK_TASK_RUNNER_IS_CURRENT(checker_.checker);
+ }
+
+ DebugTaskRunnerChecker checker_;
+
+ FML_DISALLOW_COPY_AND_ASSIGN(TaskRunnerAffineWeakPtrFactory);
+};
+
} // namespace fml
#endif // FLUTTER_FML_MEMORY_WEAK_PTR_H_
diff --git a/fml/memory/weak_ptr_unittest.cc b/fml/memory/weak_ptr_unittest.cc
index 42de850..86604f1 100644
--- a/fml/memory/weak_ptr_unittest.cc
+++ b/fml/memory/weak_ptr_unittest.cc
@@ -188,13 +188,13 @@
&loop2_task_start_latch]() {
fml::MessageLoop::EnsureInitializedForCurrentThread();
int data = 0;
- WeakPtrFactory<int> factory(&data);
+ TaskRunnerAffineWeakPtrFactory<int> factory(&data);
loop2 = &fml::MessageLoop::GetCurrent();
loop2->GetTaskRunner()->PostTask([&]() {
latch2.Signal();
loop2_task_start_latch.Wait();
- TaskRunnerAffineWeakPtr<int> ptr = factory.GetTaskRunnerAffineWeakPtr();
+ TaskRunnerAffineWeakPtr<int> ptr = factory.GetWeakPtr();
EXPECT_EQ(*ptr, data);
loop2_task_finish_latch.Signal();
});
diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc
index 74329c9..4f619ad 100644
--- a/shell/common/rasterizer.cc
+++ b/shell/common/rasterizer.cc
@@ -54,10 +54,11 @@
Rasterizer::~Rasterizer() = default;
fml::TaskRunnerAffineWeakPtr<Rasterizer> Rasterizer::GetWeakPtr() const {
- return weak_factory_.GetTaskRunnerAffineWeakPtr();
+ return weak_factory_.GetWeakPtr();
}
-fml::WeakPtr<SnapshotDelegate> Rasterizer::GetSnapshotDelegate() const {
+fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> Rasterizer::GetSnapshotDelegate()
+ const {
return weak_factory_.GetWeakPtr();
}
@@ -155,7 +156,7 @@
switch (consume_result) {
case PipelineConsumeResult::MoreAvailable: {
task_runners_.GetRasterTaskRunner()->PostTask(
- [weak_this = weak_factory_.GetTaskRunnerAffineWeakPtr(), pipeline]() {
+ [weak_this = weak_factory_.GetWeakPtr(), pipeline]() {
if (weak_this) {
weak_this->Draw(pipeline);
}
diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h
index 6de1a84..a254d84 100644
--- a/shell/common/rasterizer.h
+++ b/shell/common/rasterizer.h
@@ -186,7 +186,7 @@
///
fml::TaskRunnerAffineWeakPtr<Rasterizer> GetWeakPtr() const;
- fml::WeakPtr<SnapshotDelegate> GetSnapshotDelegate() const;
+ fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> GetSnapshotDelegate() const;
//----------------------------------------------------------------------------
/// @brief Sometimes, it may be necessary to render the same frame again
@@ -430,7 +430,7 @@
fml::closure next_frame_callback_;
bool user_override_resource_cache_bytes_;
std::optional<size_t> max_cache_bytes_;
- fml::WeakPtrFactory<Rasterizer> weak_factory_;
+ fml::TaskRunnerAffineWeakPtrFactory<Rasterizer> weak_factory_;
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
// |SnapshotDelegate|
diff --git a/shell/common/shell.cc b/shell/common/shell.cc
index d83fadb..fd5a581 100644
--- a/shell/common/shell.cc
+++ b/shell/common/shell.cc
@@ -338,7 +338,7 @@
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetRasterTaskRunner(), fml::MakeCopyable([this]() mutable {
this->weak_factory_gpu_ =
- std::make_unique<fml::WeakPtrFactory<Shell>>(this);
+ std::make_unique<fml::TaskRunnerAffineWeakPtrFactory<Shell>>(this);
}));
// Install service protocol handlers.
@@ -1156,7 +1156,7 @@
// never be reported until the next animation starts.
frame_timings_report_scheduled_ = true;
task_runners_.GetRasterTaskRunner()->PostDelayedTask(
- [self = weak_factory_gpu_->GetTaskRunnerAffineWeakPtr()]() {
+ [self = weak_factory_gpu_->GetWeakPtr()]() {
if (!self.get()) {
return;
}
diff --git a/shell/common/shell.h b/shell/common/shell.h
index a39884a..d959eb4 100644
--- a/shell/common/shell.h
+++ b/shell/common/shell.h
@@ -580,7 +580,7 @@
// For accessing the Shell via the raster thread, necessary for various
// rasterizer callbacks.
- std::unique_ptr<fml::WeakPtrFactory<Shell>> weak_factory_gpu_;
+ std::unique_ptr<fml::TaskRunnerAffineWeakPtrFactory<Shell>> weak_factory_gpu_;
friend class testing::ShellTest;
diff --git a/shell/gpu/gpu_surface_gl.cc b/shell/gpu/gpu_surface_gl.cc
index 14d4f03..e5fbf00 100644
--- a/shell/gpu/gpu_surface_gl.cc
+++ b/shell/gpu/gpu_surface_gl.cc
@@ -257,8 +257,8 @@
surface->getCanvas()->setMatrix(root_surface_transformation);
SurfaceFrame::SubmitCallback submit_callback =
- [weak = weak_factory_.GetTaskRunnerAffineWeakPtr()](
- const SurfaceFrame& surface_frame, SkCanvas* canvas) {
+ [weak = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame,
+ SkCanvas* canvas) {
return weak ? weak->PresentSurface(canvas) : false;
};
diff --git a/shell/gpu/gpu_surface_gl.h b/shell/gpu/gpu_surface_gl.h
index 0a08060..d299e57 100644
--- a/shell/gpu/gpu_surface_gl.h
+++ b/shell/gpu/gpu_surface_gl.h
@@ -58,7 +58,7 @@
// external view embedder is present.
const bool render_to_surface_;
bool valid_ = false;
- fml::WeakPtrFactory<GPUSurfaceGL> weak_factory_;
+ fml::TaskRunnerAffineWeakPtrFactory<GPUSurfaceGL> weak_factory_;
bool CreateOrUpdateSurfaces(const SkISize& size);
diff --git a/shell/gpu/gpu_surface_software.cc b/shell/gpu/gpu_surface_software.cc
index f15a1fc..8b2f664 100644
--- a/shell/gpu/gpu_surface_software.cc
+++ b/shell/gpu/gpu_surface_software.cc
@@ -57,8 +57,8 @@
canvas->resetMatrix();
SurfaceFrame::SubmitCallback on_submit =
- [self = weak_factory_.GetTaskRunnerAffineWeakPtr()](
- const SurfaceFrame& surface_frame, SkCanvas* canvas) -> bool {
+ [self = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame,
+ SkCanvas* canvas) -> bool {
// If the surface itself went away, there is nothing more to do.
if (!self || !self->IsValid() || canvas == nullptr) {
return false;
diff --git a/shell/gpu/gpu_surface_software.h b/shell/gpu/gpu_surface_software.h
index af4d1cb..a18f67c 100644
--- a/shell/gpu/gpu_surface_software.h
+++ b/shell/gpu/gpu_surface_software.h
@@ -41,7 +41,7 @@
// hack to make avoid allocating resources for the root surface when an
// external view embedder is present.
const bool render_to_surface_;
- fml::WeakPtrFactory<GPUSurfaceSoftware> weak_factory_;
+ fml::TaskRunnerAffineWeakPtrFactory<GPUSurfaceSoftware> weak_factory_;
FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceSoftware);
};