xref: /aosp_15_r20/external/libchrome/libchrome_tools/patches/Add-base-NoDestructor-T.patch (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard WorkerFrom c334673e96ce73cbf1a693c7c85b1450fcd3571c Mon Sep 17 00:00:00 2001
2*635a8641SAndroid Build Coastguard WorkerFrom: Ben Chan <[email protected]>
3*635a8641SAndroid Build Coastguard WorkerDate: Fri, 2 Nov 2018 23:07:01 -0700
4*635a8641SAndroid Build Coastguard WorkerSubject: [PATCH] libchrome: add base::NoDestructor<T>
5*635a8641SAndroid Build Coastguard Worker
6*635a8641SAndroid Build Coastguard WorkerCL:869351 introduces base::NoDestructor<T>, which is preferred in new
7*635a8641SAndroid Build Coastguard Workercode as a drop-in replacement for a function scoped static T* or T& that
8*635a8641SAndroid Build Coastguard Workeris dynamically initialized, and a global base::LazyInstance<T>.
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard WorkerThis CL patches libchrome to pull in base/no_destructor.h at r599267, so
11*635a8641SAndroid Build Coastguard Workerthat we can migrate existing Chrome OS code to use base::NoDestructor<T>
12*635a8641SAndroid Build Coastguard Workerbefore the next libchrome uprev.
13*635a8641SAndroid Build Coastguard Worker
14*635a8641SAndroid Build Coastguard WorkerBUG=None
15*635a8641SAndroid Build Coastguard WorkerTEST=`emerge-$BOARD librchrome`
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard WorkerChange-Id: I791a70e10da6318ea81eaaec869ba4702361289e
18*635a8641SAndroid Build Coastguard Worker---
19*635a8641SAndroid Build Coastguard Worker base/no_destructor.h | 98 ++++++++++++++++++++++++++++++++++++++++++++
20*635a8641SAndroid Build Coastguard Worker 1 file changed, 98 insertions(+)
21*635a8641SAndroid Build Coastguard Worker create mode 100644 base/no_destructor.h
22*635a8641SAndroid Build Coastguard Worker
23*635a8641SAndroid Build Coastguard Workerdiff --git base/no_destructor.h base/no_destructor.h
24*635a8641SAndroid Build Coastguard Workernew file mode 100644
25*635a8641SAndroid Build Coastguard Workerindex 0000000..21cfef8
26*635a8641SAndroid Build Coastguard Worker--- /dev/null
27*635a8641SAndroid Build Coastguard Worker+++ base/no_destructor.h
28*635a8641SAndroid Build Coastguard Worker@@ -0,0 +1,98 @@
29*635a8641SAndroid Build Coastguard Worker+// Copyright 2018 The Chromium Authors. All rights reserved.
30*635a8641SAndroid Build Coastguard Worker+// Use of this source code is governed by a BSD-style license that can be
31*635a8641SAndroid Build Coastguard Worker+// found in the LICENSE file.
32*635a8641SAndroid Build Coastguard Worker+
33*635a8641SAndroid Build Coastguard Worker+#ifndef BASE_NO_DESTRUCTOR_H_
34*635a8641SAndroid Build Coastguard Worker+#define BASE_NO_DESTRUCTOR_H_
35*635a8641SAndroid Build Coastguard Worker+
36*635a8641SAndroid Build Coastguard Worker+#include <new>
37*635a8641SAndroid Build Coastguard Worker+#include <utility>
38*635a8641SAndroid Build Coastguard Worker+
39*635a8641SAndroid Build Coastguard Worker+namespace base {
40*635a8641SAndroid Build Coastguard Worker+
41*635a8641SAndroid Build Coastguard Worker+// A wrapper that makes it easy to create an object of type T with static
42*635a8641SAndroid Build Coastguard Worker+// storage duration that:
43*635a8641SAndroid Build Coastguard Worker+// - is only constructed on first access
44*635a8641SAndroid Build Coastguard Worker+// - never invokes the destructor
45*635a8641SAndroid Build Coastguard Worker+// in order to satisfy the styleguide ban on global constructors and
46*635a8641SAndroid Build Coastguard Worker+// destructors.
47*635a8641SAndroid Build Coastguard Worker+//
48*635a8641SAndroid Build Coastguard Worker+// Runtime constant example:
49*635a8641SAndroid Build Coastguard Worker+// const std::string& GetLineSeparator() {
50*635a8641SAndroid Build Coastguard Worker+//  // Forwards to std::string(size_t, char, const Allocator&) constructor.
51*635a8641SAndroid Build Coastguard Worker+//   static const base::NoDestructor<std::string> s(5, '-');
52*635a8641SAndroid Build Coastguard Worker+//   return *s;
53*635a8641SAndroid Build Coastguard Worker+// }
54*635a8641SAndroid Build Coastguard Worker+//
55*635a8641SAndroid Build Coastguard Worker+// More complex initialization with a lambda:
56*635a8641SAndroid Build Coastguard Worker+// const std::string& GetSessionNonce() {
57*635a8641SAndroid Build Coastguard Worker+//   static const base::NoDestructor<std::string> nonce([] {
58*635a8641SAndroid Build Coastguard Worker+//     std::string s(16);
59*635a8641SAndroid Build Coastguard Worker+//     crypto::RandString(s.data(), s.size());
60*635a8641SAndroid Build Coastguard Worker+//     return s;
61*635a8641SAndroid Build Coastguard Worker+//   }());
62*635a8641SAndroid Build Coastguard Worker+//   return *nonce;
63*635a8641SAndroid Build Coastguard Worker+// }
64*635a8641SAndroid Build Coastguard Worker+//
65*635a8641SAndroid Build Coastguard Worker+// NoDestructor<T> stores the object inline, so it also avoids a pointer
66*635a8641SAndroid Build Coastguard Worker+// indirection and a malloc. Also note that since C++11 static local variable
67*635a8641SAndroid Build Coastguard Worker+// initialization is thread-safe and so is this pattern. Code should prefer to
68*635a8641SAndroid Build Coastguard Worker+// use NoDestructor<T> over:
69*635a8641SAndroid Build Coastguard Worker+// - A function scoped static T* or T& that is dynamically initialized.
70*635a8641SAndroid Build Coastguard Worker+// - A global base::LazyInstance<T>.
71*635a8641SAndroid Build Coastguard Worker+//
72*635a8641SAndroid Build Coastguard Worker+// Note that since the destructor is never run, this *will* leak memory if used
73*635a8641SAndroid Build Coastguard Worker+// as a stack or member variable. Furthermore, a NoDestructor<T> should never
74*635a8641SAndroid Build Coastguard Worker+// have global scope as that may require a static initializer.
75*635a8641SAndroid Build Coastguard Worker+template <typename T>
76*635a8641SAndroid Build Coastguard Worker+class NoDestructor {
77*635a8641SAndroid Build Coastguard Worker+ public:
78*635a8641SAndroid Build Coastguard Worker+  // Not constexpr; just write static constexpr T x = ...; if the value should
79*635a8641SAndroid Build Coastguard Worker+  // be a constexpr.
80*635a8641SAndroid Build Coastguard Worker+  template <typename... Args>
81*635a8641SAndroid Build Coastguard Worker+  explicit NoDestructor(Args&&... args) {
82*635a8641SAndroid Build Coastguard Worker+    new (storage_) T(std::forward<Args>(args)...);
83*635a8641SAndroid Build Coastguard Worker+  }
84*635a8641SAndroid Build Coastguard Worker+
85*635a8641SAndroid Build Coastguard Worker+  // Allows copy and move construction of the contained type, to allow
86*635a8641SAndroid Build Coastguard Worker+  // construction from an initializer list, e.g. for std::vector.
87*635a8641SAndroid Build Coastguard Worker+  explicit NoDestructor(const T& x) { new (storage_) T(x); }
88*635a8641SAndroid Build Coastguard Worker+  explicit NoDestructor(T&& x) { new (storage_) T(std::move(x)); }
89*635a8641SAndroid Build Coastguard Worker+
90*635a8641SAndroid Build Coastguard Worker+  NoDestructor(const NoDestructor&) = delete;
91*635a8641SAndroid Build Coastguard Worker+  NoDestructor& operator=(const NoDestructor&) = delete;
92*635a8641SAndroid Build Coastguard Worker+
93*635a8641SAndroid Build Coastguard Worker+  ~NoDestructor() = default;
94*635a8641SAndroid Build Coastguard Worker+
95*635a8641SAndroid Build Coastguard Worker+  const T& operator*() const { return *get(); }
96*635a8641SAndroid Build Coastguard Worker+  T& operator*() { return *get(); }
97*635a8641SAndroid Build Coastguard Worker+
98*635a8641SAndroid Build Coastguard Worker+  const T* operator->() const { return get(); }
99*635a8641SAndroid Build Coastguard Worker+  T* operator->() { return get(); }
100*635a8641SAndroid Build Coastguard Worker+
101*635a8641SAndroid Build Coastguard Worker+  const T* get() const { return reinterpret_cast<const T*>(storage_); }
102*635a8641SAndroid Build Coastguard Worker+  T* get() { return reinterpret_cast<T*>(storage_); }
103*635a8641SAndroid Build Coastguard Worker+
104*635a8641SAndroid Build Coastguard Worker+ private:
105*635a8641SAndroid Build Coastguard Worker+  alignas(T) char storage_[sizeof(T)];
106*635a8641SAndroid Build Coastguard Worker+
107*635a8641SAndroid Build Coastguard Worker+#if defined(LEAK_SANITIZER)
108*635a8641SAndroid Build Coastguard Worker+  // TODO(https://crbug.com/812277): This is a hack to work around the fact
109*635a8641SAndroid Build Coastguard Worker+  // that LSan doesn't seem to treat NoDestructor as a root for reachability
110*635a8641SAndroid Build Coastguard Worker+  // analysis. This means that code like this:
111*635a8641SAndroid Build Coastguard Worker+  //   static base::NoDestructor<std::vector<int>> v({1, 2, 3});
112*635a8641SAndroid Build Coastguard Worker+  // is considered a leak. Using the standard leak sanitizer annotations to
113*635a8641SAndroid Build Coastguard Worker+  // suppress leaks doesn't work: std::vector is implicitly constructed before
114*635a8641SAndroid Build Coastguard Worker+  // calling the base::NoDestructor constructor.
115*635a8641SAndroid Build Coastguard Worker+  //
116*635a8641SAndroid Build Coastguard Worker+  // Unfortunately, I haven't been able to demonstrate this issue in simpler
117*635a8641SAndroid Build Coastguard Worker+  // reproductions: until that's resolved, hold an explicit pointer to the
118*635a8641SAndroid Build Coastguard Worker+  // placement-new'd object in leak sanitizer mode to help LSan realize that
119*635a8641SAndroid Build Coastguard Worker+  // objects allocated by the contained type are still reachable.
120*635a8641SAndroid Build Coastguard Worker+  T* storage_ptr_ = reinterpret_cast<T*>(storage_);
121*635a8641SAndroid Build Coastguard Worker+#endif  // defined(LEAK_SANITIZER)
122*635a8641SAndroid Build Coastguard Worker+};
123*635a8641SAndroid Build Coastguard Worker+
124*635a8641SAndroid Build Coastguard Worker+}  // namespace base
125*635a8641SAndroid Build Coastguard Worker+
126*635a8641SAndroid Build Coastguard Worker+#endif  // BASE_NO_DESTRUCTOR_H_
127*635a8641SAndroid Build Coastguard Worker--
128*635a8641SAndroid Build Coastguard Worker2.19.1.930.g4563a0d9d0-goog
129*635a8641SAndroid Build Coastguard Worker
130