diff --git a/folly/detail/ThreadLocalDetail.cpp b/folly/detail/ThreadLocalDetail.cpp index f5f463f7476..00038717b4b 100644 --- a/folly/detail/ThreadLocalDetail.cpp +++ b/folly/detail/ThreadLocalDetail.cpp @@ -31,6 +31,36 @@ constexpr auto kBigGrowthFactor = 1.7; namespace folly { namespace threadlocal_detail { +struct ThreadEntry::LocalSet { + using Map = std::unordered_map; + Synchronized tracking; +}; + +FOLLY_NOINLINE ThreadEntry::LocalSet* ThreadEntry::newLocalSet() { + return new ThreadEntry::LocalSet(); +} + +FOLLY_NOINLINE ThreadEntry::LocalLifetime::LocalLifetime( + LocalSet& set, LocalCache& cache) noexcept + : caches{set} { + DCHECK(!cache.poison); + auto tracking = caches.tracking.wlock(); + auto inserted = tracking->emplace(this, &cache).second; + DCHECK(inserted); +} + +FOLLY_NOINLINE ThreadEntry::LocalLifetime::~LocalLifetime() { + auto tracking = caches.tracking.wlock(); + auto it = tracking->find(this); + DCHECK(it != tracking->end()); + DCHECK(it->second); + auto& cache = *it->second; + tracking->erase(it); + DCHECK(!cache.poison); + cache = {}; + cache.poison = true; +} + bool ThreadEntrySet::basicSanity() const { return // threadEntries.size() == entryToVectorSlot.size() && diff --git a/folly/detail/ThreadLocalDetail.h b/folly/detail/ThreadLocalDetail.h index 2fd07bc367b..e200e82b48c 100644 --- a/folly/detail/ThreadLocalDetail.h +++ b/folly/detail/ThreadLocalDetail.h @@ -173,31 +173,13 @@ struct ThreadEntry { struct LocalLifetime; - struct LocalSet { - using Map = std::unordered_map; - Synchronized tracking; - }; + struct LocalSet; + static LocalSet* newLocalSet(); struct LocalLifetime { LocalSet& caches; - explicit LocalLifetime(LocalSet& set, LocalCache& cache) noexcept - : caches{set} { - DCHECK(!cache.poison); - auto tracking = caches.tracking.wlock(); - auto inserted = tracking->emplace(this, &cache).second; - DCHECK(inserted); - } - ~LocalLifetime() { - auto tracking = caches.tracking.wlock(); - auto it = tracking->find(this); - DCHECK(it != tracking->end()); - DCHECK(it->second); - auto& cache = *it->second; - tracking->erase(it); - DCHECK(!cache.poison); - cache = {}; - cache.poison = true; - } + explicit LocalLifetime(LocalSet& set, LocalCache& cache) noexcept; + ~LocalLifetime(); }; ElementWrapper* elements{nullptr}; @@ -775,7 +757,7 @@ struct FOLLY_EXPORT StaticMeta final : StaticMetaBase { int ret = pthread_setspecific(key, threadEntry); checkPosixError(ret, "pthread_setspecific failed"); - threadEntry->caches = new ThreadEntry::LocalSet(); + threadEntry->caches = ThreadEntry::newLocalSet(); } return threadEntry; }