Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: third_party/WebKit/Source/wtf/StdLibExtras.h

Issue 2680843006: Tidy DEFINE_(THREAD_SAFE_)STATIC_LOCAL() implementations. (Closed)
Patch Set: drop no-ScriptWrappable dcheck support Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/wtf/StdLibExtras.h
diff --git a/third_party/WebKit/Source/wtf/StdLibExtras.h b/third_party/WebKit/Source/wtf/StdLibExtras.h
index 26ba1d8d02958298aacfc73daea5743ccbbce201..cf6a5eddd80ff39b3a3378e4f43043b3df6798e6 100644
--- a/third_party/WebKit/Source/wtf/StdLibExtras.h
+++ b/third_party/WebKit/Source/wtf/StdLibExtras.h
@@ -26,26 +26,98 @@
#ifndef WTF_StdLibExtras_h
#define WTF_StdLibExtras_h
+#include <cstddef>
#include "base/numerics/safe_conversions.h"
#include "wtf/Assertions.h"
#include "wtf/CPU.h"
#include "wtf/LeakAnnotations.h"
+#include "wtf/Noncopyable.h"
#include "wtf/TypeTraits.h"
-#include <cstddef>
#if DCHECK_IS_ON()
-#include "wtf/Noncopyable.h"
#include "wtf/Threading.h"
+#endif
-class WTF_EXPORT StaticLocalVerifier {
- WTF_MAKE_NONCOPYABLE(StaticLocalVerifier);
+// Use |DEFINE_STATIC_LOCAL()| to declare and define a static local variable
+// (|static T;|) so that it is leaked and its destructors are not called at
+// exit. T may also be a Blink garbage collected object, in which case it is
+// wrapped up by an off-heap |Persistent<T>| reference to the object, keeping
+// it alive across GCs.
+//
+#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \
+ static WTF::StaticSingleton<Type> s_##Name( \
+ new WTF::StaticSingleton<Type>::WrapperType Arguments); \
+ Type& Name = s_##Name.get()
+
+namespace blink {
+template <typename T>
+class Persistent;
+
+} // namespace blink
+
+namespace WTF {
+
+template <typename Type>
+class StaticSingleton final {
+ WTF_MAKE_NONCOPYABLE(StaticSingleton);
public:
- StaticLocalVerifier()
- : m_safelyInitialized(WTF::isBeforeThreadCreated()),
- m_thread(WTF::internal::currentThreadSyscall()) {}
+ template <typename T,
+ bool = WTF::IsGarbageCollectedType<T>::value &&
+ !WTF::IsPersistentReferenceType<T>::value>
+ struct Wrapper {
+ using type = T;
+
+ static T& unwrap(T* singleton) { return *singleton; }
+ };
+
+ template <typename T>
+ struct Wrapper<T, true> {
+ using type = blink::Persistent<T>;
+
+ static T& unwrap(blink::Persistent<T>* singleton) {
+ DCHECK(singleton);
+ // If this assert triggers, you're supplying an empty ("()") 'Arguments'
+ // argument to DEFINE_STATIC_LOCAL() - it must be the heap object you wish
+ // to create as a static singleton and wrapped up with a Persistent
+ // reference.
+ DCHECK(*singleton);
+ return **singleton;
+ }
+ };
+
+ using WrapperType = typename Wrapper<Type>::type;
+
+ // To cooperate with leak detection(LSan) for Blink garbage collected objects,
+ // the objects owned by persistent local statics will in some cases have to be
+ // finalized prior to leak checking. This only applies to static references to
+ // Blink heap objects and what they transitively hold on to. Hence the
+ // LEAK_SANITIZER_REGISTER_STATIC_LOCAL() use, it taking care of the grungy
+ // details.
+
+ explicit StaticSingleton(WrapperType* instance)
+ : m_instance(LEAK_SANITIZER_REGISTER_STATIC_LOCAL(WrapperType, instance))
+#if DCHECK_IS_ON()
+ ,
+ m_safelyInitialized(WTF::isBeforeThreadCreated()),
+ m_thread(WTF::internal::currentThreadSyscall())
+#endif
+ {
+ }
+
+ Type& get() const {
+#if DCHECK_IS_ON()
+ DCHECK(isNotRacy());
+#endif
+ return Wrapper<Type>::unwrap(m_instance);
+ }
- bool isNotRacy() {
+ operator Type&() { return get(); }
+
+ private:
+#if DCHECK_IS_ON()
+
+ bool isNotRacy() const {
// Make sure that this 1) is safely initialized, 2) keeps being called
// on the same thread, or 3) is called within
// AtomicallyInitializedStatic (i.e. with a lock held).
@@ -53,72 +125,16 @@ class WTF_EXPORT StaticLocalVerifier {
m_thread == WTF::internal::currentThreadSyscall() ||
WTF::isAtomicallyInitializedStaticMutexLockHeld();
dcheng 2017/02/15 08:29:56 Since we have threadsafe function-local statics by
sof 2017/02/15 08:44:57 https://codereview.chromium.org/874203002#msg11 co
}
+#endif
- private:
+ WrapperType* m_instance;
+#if DCHECK_IS_ON()
bool m_safelyInitialized;
ThreadIdentifier m_thread;
-};
#endif
-
-namespace blink {
-template <typename T>
-class Persistent;
};
-template <typename T,
- bool = WTF::IsGarbageCollectedType<T>::value &&
- !WTF::IsPersistentReferenceType<T>::value>
-class StaticLocalWrapper {
- public:
- using WrapType = T;
-
- static T& unwrap(T* singleton) { return *singleton; }
-};
-
-template <typename T>
-class StaticLocalWrapper<T, true> {
- public:
- using WrapType = blink::Persistent<T>;
-
- static T& unwrap(blink::Persistent<T>* singleton) {
- DCHECK(singleton);
- // If this assert triggers, you're supplying an empty ("()") 'Arguments'
- // argument to DEFINE_STATIC_LOCAL() - it must be the heap object you wish
- // to create as a static singleton and wrapped up with a Persistent
- // reference.
- DCHECK(*singleton);
- return **singleton;
- }
-};
-
-#if DCHECK_IS_ON()
-#define DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name) \
- static StaticLocalVerifier Name##StaticLocalVerifier; \
- DCHECK(Name##StaticLocalVerifier.isNotRacy())
-#else
-#define DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name)
-#endif
-
-// Use DEFINE_STATIC_LOCAL() to declare and define a static local variable
-// (static T;) so that it is leaked and its destructors are not called at exit.
-// T may also be a Blink garbage collected object, in which case it is
-// wrapped up by an off-heap Persistent<T> reference to the object, keeping
-// it alive across GCs.
-//
-// To cooperate with leak detection(LSan) for Blink garbage collected objects,
-// the objects owned by persistent local statics will in some cases have to be
-// finalized prior to leak checking. This only applies to static references to
-// Blink heap objects and what they transitively hold on to. Hence the
-// LEAK_SANITIZER_REGISTER_STATIC_LOCAL() use, it taking care of the grungy
-// details.
-//
-#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \
- DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name); \
- using WrappedTypeFor##Name = StaticLocalWrapper<Type>::WrapType; \
- static WrappedTypeFor##Name* WrappedInstanceFor##Name = \
- LEAK_SANITIZER_REGISTER_STATIC_LOCAL( \
- WrappedTypeFor##Name, new WrappedTypeFor##Name Arguments); \
- Type& Name = StaticLocalWrapper<Type>::unwrap(WrappedInstanceFor##Name);
+} // namespace WTF
// Use this to declare and define a static local pointer to a ref-counted object
// so that it is leaked so that the object's destructors are not called at
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698