Include <cassert> when using assert
[folly.git] / folly / detail / ThreadLocalDetail.h
index 6aaccc2b2c1a9579a7f9d902523d6c3e6659e437..418889ff117b3b6d401f47e3a2f70381de9f20ce 100644 (file)
@@ -43,7 +43,7 @@
 //
 // XXX: Ideally we would instead determine if emutls is in use at runtime as it
 // is possible to configure glibc on Linux to use emutls regardless.
-#if !FOLLY_MOBILE && !defined(__APPLE__)
+#if !FOLLY_MOBILE && !defined(__APPLE__) && !defined(_MSC_VER)
 #define FOLLY_TLD_USE_FOLLY_TLS 1
 #else
 #undef FOLLY_TLD_USE_FOLLY_TLS
@@ -254,9 +254,9 @@ struct StaticMetaBase {
     }
   };
 
-  explicit StaticMetaBase(ThreadEntry* (*threadEntry)());
+  StaticMetaBase(ThreadEntry* (*threadEntry)(), bool strict);
 
-  ~StaticMetaBase() {
+  [[noreturn]] ~StaticMetaBase() {
     LOG(FATAL) << "StaticMeta lives forever!";
   }
 
@@ -296,9 +296,11 @@ struct StaticMetaBase {
   uint32_t nextId_;
   std::vector<uint32_t> freeIds_;
   std::mutex lock_;
+  SharedMutex accessAllThreadsLock_;
   pthread_key_t pthreadKey_;
   ThreadEntry head_;
   ThreadEntry* (*threadEntry_)();
+  bool strict_;
 };
 
 // Held in a singleton to track our global instances.
@@ -308,19 +310,23 @@ struct StaticMetaBase {
 // Creating and destroying ThreadLocalPtr objects, as well as thread exit
 // for threads that use ThreadLocalPtr objects collide on a lock inside
 // StaticMeta; you can specify multiple Tag types to break that lock.
-template <class Tag>
+template <class Tag, class AccessMode>
 struct StaticMeta : StaticMetaBase {
-  StaticMeta() : StaticMetaBase(&StaticMeta::getThreadEntrySlow) {
+  StaticMeta()
+      : StaticMetaBase(
+            &StaticMeta::getThreadEntrySlow,
+            std::is_same<AccessMode, AccessModeStrict>::value) {
     registerAtFork(
         /*prepare*/ &StaticMeta::preFork,
         /*parent*/ &StaticMeta::onForkParent,
         /*child*/ &StaticMeta::onForkChild);
   }
 
-  static StaticMeta<Tag>& instance() {
+  static StaticMeta<Tag, AccessMode>& instance() {
     // Leak it on exit, there's only one per process and we don't have to
     // worry about synchronization with exiting threads.
-    static auto instance = detail::createGlobal<StaticMeta<Tag>, void>();
+    /* library-local */ static auto instance =
+        detail::createGlobal<StaticMeta<Tag, AccessMode>, void>();
     return *instance;
   }