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

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

Issue 2680843006: Tidy DEFINE_(THREAD_SAFE_)STATIC_LOCAL() implementations. (Closed)
Patch Set: simplify DEFINE_THREAD_SAFE_STATIC_LOCAL() 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 | third_party/WebKit/Source/wtf/Threading.h » ('j') | 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..d2633948b98bd909e46ffdcac39b7d20d50e03e4 100644
--- a/third_party/WebKit/Source/wtf/StdLibExtras.h
+++ b/third_party/WebKit/Source/wtf/StdLibExtras.h
@@ -26,99 +26,127 @@
#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);
-
- public:
- StaticLocalVerifier()
- : m_safelyInitialized(WTF::isBeforeThreadCreated()),
- m_thread(WTF::internal::currentThreadSyscall()) {}
-
- bool isNotRacy() {
- // 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).
- return m_safelyInitialized ||
- m_thread == WTF::internal::currentThreadSyscall() ||
- WTF::isAtomicallyInitializedStaticMutexLockHeld();
- }
+// 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.
+//
+// A |DEFINE_STATIC_LOCAL()| static should only be used on the thread it was
+// created on.
+//
+#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \
+ static WTF::StaticSingleton<Type> s_##Name( \
+ new WTF::StaticSingleton<Type>::WrapperType Arguments); \
+ Type& Name = s_##Name.get(false)
- private:
- bool m_safelyInitialized;
- ThreadIdentifier m_thread;
-};
-#endif
+// |DEFINE_THREAD_SAFE_STATIC_LOCAL()| is the cross-thread accessible variant
+// of |DEFINE_STATIC_LOCAL()|; use it if the singleton can be accessed by
+// multiple threads.
+//
+// TODO: rename as DEFINE_CROSS_THREAD_STATIC_LOCAL() ?
+#define DEFINE_THREAD_SAFE_STATIC_LOCAL(Type, Name, Initializer) \
+ static WTF::StaticSingleton<Type> s_##Name(Initializer); \
+ Type& Name = s_##Name.get(true)
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;
+} // namespace blink
- static T& unwrap(T* singleton) { return *singleton; }
-};
+namespace WTF {
+
+template <typename Type>
+class StaticSingleton final {
+ WTF_MAKE_NONCOPYABLE(StaticSingleton);
-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;
+ 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(bool allowCrossThreadUse) const {
#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)
+ DCHECK(isNotRacy(allowCrossThreadUse));
#endif
+ ALLOW_UNUSED_LOCAL(allowCrossThreadUse);
+ return Wrapper<Type>::unwrap(m_instance);
+ }
-// 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);
+ operator Type&() { return get(); }
+
+ private:
+#if DCHECK_IS_ON()
+
+ bool isNotRacy(bool allowCrossThreadUse) const {
+ // Make sure that singleton is safely initialized, or
+ // keeps being called on the same thread if cross-thread
+ // use is not permitted.
+ return allowCrossThreadUse || m_safelyInitialized ||
sof 2017/02/17 06:37:01 fyi, https://codereview.chromium.org/2698953002/ h
+ m_thread == WTF::internal::currentThreadSyscall();
+ }
+#endif
+
+ WrapperType* m_instance;
+#if DCHECK_IS_ON()
+ bool m_safelyInitialized;
+ ThreadIdentifier m_thread;
+#endif
+};
+
+} // 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 | third_party/WebKit/Source/wtf/Threading.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698