X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FSingleton.cpp;h=7d3eeac61cf377d8cce358251c227c48ddfd2e7d;hb=5ba3126fb76f1d81100b34e429c79cd21f8cd142;hp=fe8d7db7a17b38b4e94e43b557fdd972918a04ab;hpb=0416e1ea440f816d5543feb5e834f09906ddfcab;p=folly.git diff --git a/folly/Singleton.cpp b/folly/Singleton.cpp index fe8d7db7..7d3eeac6 100644 --- a/folly/Singleton.cpp +++ b/folly/Singleton.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,28 +16,48 @@ #include +#ifndef _WIN32 +#include +#endif + #include #include #include -#include +#include #include -#include #include +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) +static void hs_init_weak(int* argc, char** argv[]) + __attribute__((__weakref__("hs_init"))); +#endif + namespace folly { +SingletonVault::Type SingletonVault::defaultVaultType() { +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) + bool isPython = dlsym(RTLD_DEFAULT, "Py_Main"); + bool isHaskel = &::hs_init_weak || dlsym(RTLD_DEFAULT, "hs_init"); + bool isJVM = dlsym(RTLD_DEFAULT, "JNI_GetCreatedJavaVMs"); + bool isD = dlsym(RTLD_DEFAULT, "_d_run_main"); + + return isPython || isHaskel || isJVM || isD ? Type::Relaxed : Type::Strict; +#else + return Type::Relaxed; +#endif +} + namespace detail { [[noreturn]] void singletonWarnDoubleRegistrationAndAbort( const TypeDescriptor& type) { - // Not using LOG(FATAL) or std::cerr because they may not be initialized yet. - std::ostringstream o; - o << "Double registration of singletons of the same " - << "underlying type; check for multiple definitions " - << "of type folly::Singleton<" << type.name() << ">" << std::endl; - auto s = o.str(); - writeFull(STDERR_FILENO, s.data(), s.size()); + // Ensure the availability of std::cerr + std::ios_base::Init ioInit; + std::cerr << "Double registration of singletons of the same " + "underlying type; check for multiple definitions " + "of type folly::Singleton<" + << type.name() << ">\n"; std::abort(); } } @@ -105,12 +125,17 @@ void SingletonVault::registrationComplete() { auto state = state_.wlock(); stateCheck(SingletonVaultState::Running, *state); + if (state->registrationComplete) { + return; + } + auto singletons = singletons_.rlock(); if (type_ == Type::Strict) { for (const auto& p : *singletons) { if (p.second->hasLiveInstance()) { throw std::runtime_error( - "Singleton created before registration was complete."); + "Singleton " + p.first.name() + + " created before registration was complete."); } } }