File: cross_thread_handle_internal.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (189 lines) | stat: -rw-r--r-- 6,718 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_INTERNAL_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_INTERNAL_H_

#include "base/functional/bind.h"
#include "base/threading/platform_thread.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "v8/include/cppgc/cross-thread-persistent.h"
#include "v8/include/cppgc/source-location.h"

// Required to optimize away locations for builds that do not need them to avoid
// binary size blowup.
// Same as in `platform/heap/persistent.h`. Avoiding the include to avoid
// exposing other types that are harder to use in concurrent contexts.
#if BUILDFLAG(VERBOSE_PERSISTENT)
#define CROSS_THREAD_HANDLE_LOCATION_FROM_HERE \
  blink::CrossThreadHandleLocation::Current()
#else  // !BUILDFLAG(VERBOSE_PERSISTENT)
#define CROSS_THREAD_HANDLE_LOCATION_FROM_HERE \
  blink::CrossThreadHandleLocation()
#endif  // !BUILDFLAG(VERBOSE_PERSISTENT)

namespace blink {

template <typename T, typename WeaknessPolicy>
class BasicUnwrappingCrossThreadHandle;

// A source location that is used for tracking creation of
// `CrossThreadHandle` and `CrossThreadWeakHandle` in debugging
// configurations.
using CrossThreadHandleLocation = cppgc::SourceLocation;

namespace internal {

struct StrongCrossThreadHandleWeaknessPolicy {
  template <typename T>
  using InternalRefType = cppgc::subtle::CrossThreadPersistent<T>;
};

struct WeakCrossThreadHandleWeaknessPolicy {
  template <typename T>
  using InternalRefType = cppgc::subtle::WeakCrossThreadPersistent<T>;
};

template <typename T, typename WeaknessPolicy>
class BasicCrossThreadHandle {
 public:
  explicit BasicCrossThreadHandle(T* raw,
                                  const CrossThreadHandleLocation& loc =
                                      CROSS_THREAD_HANDLE_LOCATION_FROM_HERE)
      : ref_(raw, loc) {}

  ~BasicCrossThreadHandle() = default;
  BasicCrossThreadHandle(BasicCrossThreadHandle&&) = default;
  // Required by CrossThreadCopier.
  BasicCrossThreadHandle(const BasicCrossThreadHandle&) = default;

  BasicCrossThreadHandle& operator=(BasicCrossThreadHandle&&) = delete;
  BasicCrossThreadHandle* operator=(const BasicCrossThreadHandle&) = delete;

 protected:
  // Returns a pointer to the garbage collected object. Must only be used from
  // the creation thread and will crash if invoked on any other thread.
  T* GetOnCreationThread() const {
    CHECK_EQ(creation_thread_id_, base::PlatformThread::CurrentId());
    return ref_.Get();
  }

  // Clears the stored object.
  void Clear() { ref_.Clear(); }

 private:
  template <typename U, typename V>
  friend class blink::BasicUnwrappingCrossThreadHandle;

  typename WeaknessPolicy::template InternalRefType<T> ref_;
  const base::PlatformThreadId creation_thread_id_ =
      base::PlatformThread::CurrentId();
};

template <typename T, typename WeaknessPolicy>
class BasicUnwrappingCrossThreadHandle final
    : public BasicCrossThreadHandle<T, WeaknessPolicy> {
  using Base = BasicCrossThreadHandle<T, WeaknessPolicy>;

 public:
  explicit BasicUnwrappingCrossThreadHandle(
      BasicCrossThreadHandle<T, WeaknessPolicy>&& handle)
      : Base(std::move(handle)) {}
  explicit BasicUnwrappingCrossThreadHandle(
      const BasicCrossThreadHandle<T, WeaknessPolicy>& handle)
      : Base(handle) {}
  explicit BasicUnwrappingCrossThreadHandle(
      T* raw,
      const CrossThreadHandleLocation& loc =
          CROSS_THREAD_HANDLE_LOCATION_FROM_HERE)
      : Base(raw, loc) {}

  ~BasicUnwrappingCrossThreadHandle() = default;
  BasicUnwrappingCrossThreadHandle(BasicUnwrappingCrossThreadHandle&&) =
      default;
  // Required by CrossThreadCopier.
  BasicUnwrappingCrossThreadHandle(const BasicUnwrappingCrossThreadHandle&) =
      default;

  // Re-expose the actual getter for the underlying object.
  using Base::GetOnCreationThread;

  // Re-expose the clear method for the underlying object.
  using Base::Clear;

  // Returns whether a value is set.  May only be accessed on the thread the
  // original CrossThreadHandle object was created.
  //
  // Exposed so the callback implementation can test if weak handles are still
  // live before trying to run the callback.
  explicit operator bool() const { return Base::GetOnCreationThread(); }

  BasicUnwrappingCrossThreadHandle& operator=(
      BasicUnwrappingCrossThreadHandle&&) = delete;
  BasicUnwrappingCrossThreadHandle* operator=(
      const BasicUnwrappingCrossThreadHandle&) = delete;
};

}  // namespace internal
}  // namespace blink

namespace WTF {

template <typename T, typename WeaknessPolicy>
struct CrossThreadCopier<
    blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>>
    : public CrossThreadCopierPassThrough<
          blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>> {};

template <typename T, typename WeaknessPolicy>
struct CrossThreadCopier<
    blink::internal::BasicUnwrappingCrossThreadHandle<T, WeaknessPolicy>>
    : public CrossThreadCopierPassThrough<
          blink::internal::BasicUnwrappingCrossThreadHandle<T,
                                                            WeaknessPolicy>> {};

}  // namespace WTF

namespace base {

template <typename T>
struct IsWeakReceiver<blink::internal::BasicUnwrappingCrossThreadHandle<
    T,
    blink::internal::WeakCrossThreadHandleWeaknessPolicy>> : std::true_type {};

template <typename T, typename WeaknessPolicy>
struct BindUnwrapTraits<
    blink::internal::BasicUnwrappingCrossThreadHandle<T, WeaknessPolicy>> {
  static T* Unwrap(
      const blink::internal::BasicUnwrappingCrossThreadHandle<T,
                                                              WeaknessPolicy>&
          wrapped) {
    return wrapped.GetOnCreationThread();
  }
};

template <typename T, typename WeaknessPolicy>
struct MaybeValidTraits<
    blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>> {
  static bool MaybeValid(
      const blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>& p) {
    return true;
  }
};

template <typename T, typename WeaknessPolicy>
struct MaybeValidTraits<
    blink::internal::BasicUnwrappingCrossThreadHandle<T, WeaknessPolicy>> {
  static bool MaybeValid(
      const blink::internal::BasicUnwrappingCrossThreadHandle<T,
                                                              WeaknessPolicy>&
          p) {
    return true;
  }
};

}  // namespace base

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_INTERNAL_H_