Commit ed0cacef authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Let createGlobal return a reference

Summary: [Folly] Let `createGlobal` return a reference rather than a pointer, since it always returns non-`nullptr`.

Reviewed By: andriigrynenko

Differential Revision: D13116591

fbshipit-source-id: 5618c2e8a5a04b158ac45a3e43b02eb37c6af8c1
parent ec8d84ff
...@@ -27,7 +27,7 @@ SingletonHolder<T>& SingletonHolder<T>::singleton() { ...@@ -27,7 +27,7 @@ SingletonHolder<T>& SingletonHolder<T>::singleton() {
{typeid(T), typeid(Tag)}, {typeid(T), typeid(Tag)},
*SingletonVault::singleton<VaultTag>()) {} *SingletonVault::singleton<VaultTag>()) {}
}; };
return *createGlobal<SingletonHolderImpl, void>(); return createGlobal<SingletonHolderImpl, void>();
} }
[[noreturn]] void singletonWarnDoubleRegistrationAndAbort( [[noreturn]] void singletonWarnDoubleRegistrationAndAbort(
......
...@@ -500,14 +500,14 @@ class SingletonVault { ...@@ -500,14 +500,14 @@ class SingletonVault {
// tests only. // tests only.
template <typename VaultTag = detail::DefaultTag> template <typename VaultTag = detail::DefaultTag>
static SingletonVault* singleton() { static SingletonVault* singleton() {
return detail::createGlobal<SingletonVault, VaultTag>(); return &detail::createGlobal<SingletonVault, VaultTag>();
} }
typedef std::string (*StackTraceGetterPtr)(); typedef std::string (*StackTraceGetterPtr)();
static std::atomic<StackTraceGetterPtr>& stackTraceGetter() { static std::atomic<StackTraceGetterPtr>& stackTraceGetter() {
struct Result : std::atomic<StackTraceGetterPtr> {}; struct Result : std::atomic<StackTraceGetterPtr> {};
return *detail::createGlobal<Result, void>(); return detail::createGlobal<Result, void>();
} }
void setType(Type type) { void setType(Type type) {
...@@ -743,7 +743,7 @@ class LeakySingleton { ...@@ -743,7 +743,7 @@ class LeakySingleton {
}; };
static Entry& entryInstance() { static Entry& entryInstance() {
return *detail::createGlobal<Entry, Tag>(); return detail::createGlobal<Entry, Tag>();
} }
static T& instance() { static T& instance() {
......
...@@ -133,7 +133,7 @@ class SingletonThreadLocal { ...@@ -133,7 +133,7 @@ class SingletonThreadLocal {
SingletonThreadLocal() = delete; SingletonThreadLocal() = delete;
FOLLY_ALWAYS_INLINE static WrapperTL& getWrapperTL() { FOLLY_ALWAYS_INLINE static WrapperTL& getWrapperTL() {
return *detail::createGlobal<WrapperTL, Tag>(); return detail::createGlobal<WrapperTL, Tag>();
} }
FOLLY_NOINLINE static Wrapper& getWrapper() { FOLLY_NOINLINE static Wrapper& getWrapper() {
......
...@@ -32,12 +32,12 @@ namespace detail { ...@@ -32,12 +32,12 @@ namespace detail {
class StaticSingletonManager { class StaticSingletonManager {
public: public:
template <typename T, typename Tag> template <typename T, typename Tag>
FOLLY_EXPORT FOLLY_ALWAYS_INLINE static T* create() { FOLLY_EXPORT FOLLY_ALWAYS_INLINE static T& create() {
static Cache cache; static Cache cache;
auto const& key = typeid(TypePair<T, Tag>); auto const& key = typeid(TypePair<T, Tag>);
auto const v = cache.load(std::memory_order_acquire); auto const v = cache.load(std::memory_order_acquire);
auto const p = FOLLY_LIKELY(!!v) ? v : create_(key, make<T>, cache); auto const p = FOLLY_LIKELY(!!v) ? v : create_(key, make<T>, cache);
return static_cast<T*>(p); return *static_cast<T*>(p);
} }
private: private:
...@@ -57,7 +57,7 @@ class StaticSingletonManager { ...@@ -57,7 +57,7 @@ class StaticSingletonManager {
}; };
template <typename T, typename Tag> template <typename T, typename Tag>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal() { FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T& createGlobal() {
return StaticSingletonManager::create<T, Tag>(); return StaticSingletonManager::create<T, Tag>();
} }
......
...@@ -93,14 +93,14 @@ ThreadEntryList* StaticMetaBase::getThreadEntryList() { ...@@ -93,14 +93,14 @@ ThreadEntryList* StaticMetaBase::getThreadEntryList() {
pthread_key_t pthreadKey_; pthread_key_t pthreadKey_;
}; };
auto instance = detail::createGlobal<PthreadKey, void>(); auto& instance = detail::createGlobal<PthreadKey, void>();
ThreadEntryList* threadEntryList = ThreadEntryList* threadEntryList =
static_cast<ThreadEntryList*>(pthread_getspecific(instance->get())); static_cast<ThreadEntryList*>(pthread_getspecific(instance.get()));
if (UNLIKELY(!threadEntryList)) { if (UNLIKELY(!threadEntryList)) {
threadEntryList = new ThreadEntryList(); threadEntryList = new ThreadEntryList();
int ret = pthread_setspecific(instance->get(), threadEntryList); int ret = pthread_setspecific(instance.get(), threadEntryList);
checkPosixError(ret, "pthread_setspecific failed"); checkPosixError(ret, "pthread_setspecific failed");
} }
......
...@@ -428,7 +428,7 @@ struct StaticMeta final : StaticMetaBase { ...@@ -428,7 +428,7 @@ struct StaticMeta final : StaticMetaBase {
static StaticMeta<Tag, AccessMode>& instance() { static StaticMeta<Tag, AccessMode>& instance() {
// Leak it on exit, there's only one per process and we don't have to // Leak it on exit, there's only one per process and we don't have to
// worry about synchronization with exiting threads. // worry about synchronization with exiting threads.
return *detail::createGlobal<StaticMeta<Tag, AccessMode>, void>(); return detail::createGlobal<StaticMeta<Tag, AccessMode>, void>();
} }
FOLLY_EXPORT FOLLY_ALWAYS_INLINE static ElementWrapper& get(EntryID* ent) { FOLLY_EXPORT FOLLY_ALWAYS_INLINE static ElementWrapper& get(EntryID* ent) {
......
...@@ -22,7 +22,7 @@ namespace folly { ...@@ -22,7 +22,7 @@ namespace folly {
namespace detail { namespace detail {
extern "C" int* check() { extern "C" int* check() {
return createGlobal<int, void>(); return &createGlobal<int, void>();
} }
struct StaticSingletonManagerTest : public testing::Test {}; struct StaticSingletonManagerTest : public testing::Test {};
...@@ -36,19 +36,16 @@ using Int = std::integral_constant<int, I>; ...@@ -36,19 +36,16 @@ using Int = std::integral_constant<int, I>;
TEST_F(StaticSingletonManagerTest, example) { TEST_F(StaticSingletonManagerTest, example) {
using T = std::integral_constant<int, 3>; using T = std::integral_constant<int, 3>;
auto i = createGlobal<T, Tag<char>>(); auto& i = createGlobal<T, Tag<char>>();
ASSERT_NE(nullptr, i); EXPECT_EQ(T::value, i);
EXPECT_EQ(T::value, *i);
auto j = createGlobal<T, Tag<char>>(); auto& j = createGlobal<T, Tag<char>>();
ASSERT_NE(nullptr, j); EXPECT_EQ(&i, &j);
EXPECT_EQ(i, j); EXPECT_EQ(T::value, j);
EXPECT_EQ(T::value, *j);
auto k = createGlobal<T, Tag<char*>>(); auto& k = createGlobal<T, Tag<char*>>();
ASSERT_NE(nullptr, k); EXPECT_NE(&i, &k);
EXPECT_NE(i, k); EXPECT_EQ(T::value, k);
EXPECT_EQ(T::value, *k);
} }
} // namespace detail } // namespace detail
......
...@@ -21,6 +21,6 @@ namespace folly { ...@@ -21,6 +21,6 @@ namespace folly {
FOLLY_STATIC_CTOR_PRIORITY_MAX folly::Indestructible<rcu_domain<RcuTag>*> FOLLY_STATIC_CTOR_PRIORITY_MAX folly::Indestructible<rcu_domain<RcuTag>*>
rcu_default_domain_( rcu_default_domain_(
folly::detail::createGlobal<rcu_domain<RcuTag>, RcuTag>()); &folly::detail::createGlobal<rcu_domain<RcuTag>, RcuTag>());
} // namespace folly } // namespace folly
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment