From: Andrii Grynenko Date: Wed, 24 Feb 2016 03:49:07 +0000 (-0800) Subject: Fix double definition for templated folly::Singletons X-Git-Tag: deprecate-dynamic-initializer~44 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=9dd084035d147c2918c3526e03502252038587a5;p=folly.git Fix double definition for templated folly::Singletons Summary: Allow createGlobal() to create dependent objects. Reviewed By: yfeldblum Differential Revision: D2963111 fb-gh-sync-id: 8e4da48a7a1000934963396b423e8eff98a8aade shipit-source-id: 8e4da48a7a1000934963396b423e8eff98a8aade --- diff --git a/folly/Singleton.h b/folly/Singleton.h index e083e35b..bb04862d 100644 --- a/folly/Singleton.h +++ b/folly/Singleton.h @@ -170,14 +170,23 @@ class StaticSingletonManager { template inline T* create(F&& creator) { - std::lock_guard lg(mutex_); + auto& entry = [&]() mutable -> Entry& { + std::lock_guard lg(mutex_); - auto& id = typeid(TypePair); - auto& ptr = reinterpret_cast(map_[id]); - if (!ptr) { - ptr = creator(); + auto& id = typeid(TypePair); + auto& entryPtr = reinterpret_cast*&>(map_[id]); + if (!entryPtr) { + entryPtr = new Entry(); + } + return *entryPtr; + }(); + + std::lock_guard lg(entry.mutex); + + if (!entry.ptr) { + entry.ptr = creator(); } - return ptr; + return entry.ptr; } private: @@ -186,6 +195,12 @@ class StaticSingletonManager { StaticSingletonManager() {} + template + struct Entry { + T* ptr{nullptr}; + std::mutex mutex; + }; + std::unordered_map map_; std::mutex mutex_; };