summaryrefslogtreecommitdiffstats
path: root/chromium/base/bind_internal.h
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-02-04 17:20:24 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-02-12 08:15:25 +0000
commit8fa0776f1f79e91fc9c0b9c1ba11a0a29c05196b (patch)
tree788d8d7549712682703a0310ca4a0f0860d4802b /chromium/base/bind_internal.h
parent606d85f2a5386472314d39923da28c70c60dc8e7 (diff)
BASELINE: Update Chromium to 98.0.4758.90
Change-Id: Ib7c41539bf8a8e0376bd639f27d68294de90f3c8 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/bind_internal.h')
-rw-r--r--chromium/base/bind_internal.h88
1 files changed, 74 insertions, 14 deletions
diff --git a/chromium/base/bind_internal.h b/chromium/base/bind_internal.h
index a21c8ab360e..b8670d6c089 100644
--- a/chromium/base/bind_internal.h
+++ b/chromium/base/bind_internal.h
@@ -13,10 +13,12 @@
#include <type_traits>
#include <utility>
+#include "base/allocator/buildflags.h"
#include "base/bind.h"
#include "base/callback_internal.h"
#include "base/check.h"
#include "base/compiler_specific.h"
+#include "base/memory/raw_ptr.h"
#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
@@ -44,7 +46,9 @@
// FunctorTraits<> -- Type traits used to determine the correct RunType and
// invocation manner for a Functor. This is where function
// signature adapters are applied.
-// InvokeHelper<> -- Take a Functor + arguments and actully invokes it.
+// StorageTraits<> -- Type traits that determine how a bound argument is
+// stored in BindState.
+// InvokeHelper<> -- Take a Functor + arguments and actually invokes it.
// Handle the differing syntaxes needed for WeakPtr<>
// support. This is separate from Invoker to avoid creating
// multiple version of Invoker<>.
@@ -84,7 +88,29 @@ class UnretainedWrapper {
T* get() const { return ptr_; }
private:
- T* ptr_;
+ using ImplType = std::
+ conditional_t<raw_ptr_traits::IsSupportedType<T>::value, raw_ptr<T>, T*>;
+ ImplType ptr_;
+};
+
+// Storage type for std::reference_wrapper so `BindState` can internally store
+// unprotected references using raw_ptr.
+//
+// std::reference_wrapper<T> and T& do not work, since the reference lifetime is
+// not safely protected by MiraclePtr.
+//
+// UnretainedWrapper<T> and raw_ptr<T> do not work, since BindUnwrapTraits
+// would try to pass by T* rather than T&.
+template <typename T>
+class UnretainedRefWrapper {
+ public:
+ explicit UnretainedRefWrapper(T& o) : ptr_(std::addressof(o)) {}
+ T& get() const { return *ptr_; }
+
+ private:
+ using ImplType = std::
+ conditional_t<raw_ptr_traits::IsSupportedType<T>::value, raw_ptr<T>, T*>;
+ ImplType const ptr_;
};
template <typename T>
@@ -629,6 +655,31 @@ struct FunctorTraits<RepeatingCallback<R(Args...)>> {
template <typename Functor>
using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>;
+// StorageTraits<>
+//
+// See description at top of file.
+template <typename T>
+struct StorageTraits {
+ using Type = T;
+};
+
+// For T*, store as UnretainedWrapper<T> for safety, as it internally uses
+// raw_ptr<T> (when possible).
+template <typename T>
+struct StorageTraits<T*> {
+ using Type = UnretainedWrapper<T>;
+};
+
+// Unwrap std::reference_wrapper and store it in a custom wrapper so that
+// references are also protected with raw_ptr<T>.
+template <typename T>
+struct StorageTraits<std::reference_wrapper<T>> {
+ using Type = UnretainedRefWrapper<T>;
+};
+
+template <typename T>
+using MakeStorageType = typename StorageTraits<std::decay_t<T>>::Type;
+
// InvokeHelper<>
//
// There are 2 logical InvokeHelper<> specializations: normal, WeakCalls.
@@ -818,17 +869,22 @@ BanUnconstructedRefCountedReceiver(const Receiver& receiver, Unused&&...) {
DCHECK(receiver);
// It's error prone to make the implicit first reference to ref-counted types.
- // In the example below, base::BindOnce() makes the implicit first reference
- // to the ref-counted Foo. If PostTask() failed or the posted task ran fast
- // enough, the newly created instance can be destroyed before |oo| makes
- // another reference.
+ // In the example below, base::BindOnce() would make the implicit first
+ // reference to the ref-counted Foo. If PostTask() failed or the posted task
+ // ran fast enough, the newly created instance could be destroyed before `oo`
+ // makes another reference.
// Foo::Foo() {
// base::PostTask(FROM_HERE, base::BindOnce(&Foo::Bar, this));
// }
//
// scoped_refptr<Foo> oo = new Foo();
//
- // Instead of doing like above, please consider adding a static constructor,
+ // Hence, base::Bind{Once,Repeating}() refuses to create the first reference
+ // to ref-counted objects, and DCHECK()s otherwise. As above, that typically
+ // happens around PostTask() in their constructor, and such objects can be
+ // destroyed before `new` returns if the task resolves fast enough.
+ //
+ // Instead of doing the above, please consider adding a static constructor,
// and keep the first reference alive explicitly.
// // static
// scoped_refptr<Foo> Foo::Create() {
@@ -840,11 +896,8 @@ BanUnconstructedRefCountedReceiver(const Receiver& receiver, Unused&&...) {
// Foo::Foo() {}
//
// scoped_refptr<Foo> oo = Foo::Create();
- DCHECK(receiver->HasAtLeastOneRef())
- << "base::Bind{Once,Repeating}() refuses to create the first reference "
- "to ref-counted objects. That typically happens around PostTask() in "
- "their constructor, and such objects can be destroyed before `new` "
- "returns if the task resolves fast enough.";
+ //
+ DCHECK(receiver->HasAtLeastOneRef());
}
// BindState<>
@@ -930,7 +983,7 @@ template <typename Functor, typename... BoundArgs>
struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> {
static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value,
"A parameter is a refcounted type and needs scoped_refptr.");
- using Type = BindState<std::decay_t<Functor>, std::decay_t<BoundArgs>...>;
+ using Type = BindState<std::decay_t<Functor>, MakeStorageType<BoundArgs>...>;
};
template <typename Functor>
@@ -960,7 +1013,7 @@ struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> {
std::conditional_t<std::is_pointer<DecayedReceiver>::value,
scoped_refptr<std::remove_pointer_t<DecayedReceiver>>,
DecayedReceiver>,
- std::decay_t<BoundArgs>...>;
+ MakeStorageType<BoundArgs>...>;
};
template <typename Functor, typename... BoundArgs>
@@ -1313,6 +1366,13 @@ struct BindUnwrapTraits<internal::UnretainedWrapper<T>> {
};
template <typename T>
+struct BindUnwrapTraits<internal::UnretainedRefWrapper<T>> {
+ static T& Unwrap(const internal::UnretainedRefWrapper<T>& o) {
+ return o.get();
+ }
+};
+
+template <typename T>
struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> {
static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); }
};