34 #if FOLLY_USE_SYMBOLIZER 38 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) 39 #define FOLLY_SINGLETON_HAVE_DLSYM 1 44 #if FOLLY_SINGLETON_HAVE_DLSYM 52 #if FOLLY_SINGLETON_HAVE_DLSYM 53 bool isPython = dlsym(RTLD_DEFAULT,
"Py_Main");
56 bool isJVM = dlsym(RTLD_DEFAULT,
"JNI_GetCreatedJavaVMs");
57 bool isD = dlsym(RTLD_DEFAULT,
"_d_run_main");
59 return isPython || isHaskel || isJVM || isD ? Type::Relaxed : Type::Strict;
69 if (tag_ti_ != std::type_index(
typeid(
DefaultTag))) {
80 std::ios_base::Init ioInit;
81 std::cerr <<
"Double registration of singletons of the same " 82 "underlying type; check for multiple definitions " 83 "of type folly::Singleton<" 84 << type.
name() <<
">\n";
91 std::ios_base::Init ioInit;
92 std::cerr <<
"Double registration of singletons of the same " 93 "underlying type; check for multiple definitions " 94 "of type folly::LeakySingleton<" 95 << type.
name() <<
">\n";
102 LOG(
FATAL) <<
"Creating instance for unregistered singleton: " << type.
name()
106 << (
ptr ? (*ptr)() :
"(not available)");
111 LOG(
FATAL) <<
"Registering mock before singleton was registered: " 118 LOG(ERROR) <<
"Singleton of type " << type.
name() <<
" has a " 119 <<
"living reference at destroyInstances time; beware! Raw " 120 <<
"pointer is " << ptr <<
". It is very likely " 121 <<
"that some other singleton is holding a shared_ptr to it. " 122 <<
"This singleton will be leaked (even if a shared_ptr to it " 123 <<
"is eventually released)." 124 <<
"Make sure dependencies between these singletons are " 125 <<
"properly defined.";
130 LOG(
FATAL) <<
"circular singleton dependency: " << type.
name();
136 LOG(
FATAL) <<
"Creating instance for unregistered singleton: " << type.
name()
140 << (
ptr ? (*ptr)() :
"(not available)");
146 auto stack_trace = stack_trace_getter ? stack_trace_getter() :
"";
147 if (!stack_trace.empty()) {
148 stack_trace =
"Stack trace:\n" + stack_trace;
151 LOG(
FATAL) <<
"Singleton " << type.
name() <<
" requested before " 152 <<
"registrationComplete() call.\n" 153 <<
"This usually means that either main() never called " 154 <<
"folly::init, or singleton was requested before main() " 155 <<
"(which is not allowed).\n" 163 auto stack_trace = stack_trace_getter ? stack_trace_getter() :
"";
164 if (stack_trace.empty()) {
165 output +=
"Failed to get release stack trace.";
167 output +=
"Release stack trace:\n";
168 output += stack_trace;
176 "nullptr_t should be passed if you want {} to be default constructed",
178 throw std::logic_error(msg);
183 throw std::runtime_error(
184 "Raw pointer to a singleton requested after its destruction." 185 " Singleton type is: " +
199 leakedTypes +=
"\t" +
singleton.name() +
"\n";
201 LOG(
DFATAL) <<
"Singletons of the following types had living references " 202 <<
"after destroyInstances was finished:\n" 204 <<
"beware! It is very likely that those singleton instances " 212 #if defined(__APPLE__) || defined(_MSC_VER) 214 FatalHelper fatalHelper;
216 FatalHelper
__attribute__((__init_priority__(101))) fatalHelper;
226 auto state = state_.rlock();
230 LOG(ERROR) <<
"Registering singleton after registrationComplete().";
233 auto singletons = singletons_.wlock();
235 singletons->emplace(entry->
type(), entry).second, std::logic_error);
239 auto state = state_.rlock();
243 LOG(ERROR) <<
"Registering for eager-load after registrationComplete().";
246 CHECK_THROW(singletons_.rlock()->count(entry->
type()), std::logic_error);
248 auto eagerInitSingletons = eagerInitSingletons_.wlock();
249 eagerInitSingletons->insert(entry);
255 auto state = state_.wlock();
258 if (state->registrationComplete) {
262 auto singletons = singletons_.rlock();
263 if (
type_ == Type::Strict) {
264 for (
const auto& p : *singletons) {
265 if (p.second->hasLiveInstance()) {
266 throw std::runtime_error(
267 "Singleton " + p.first.name() +
268 " created before registration was complete.");
273 state->registrationComplete =
true;
278 auto state = state_.rlock();
281 throw std::logic_error(
"registrationComplete() not yet called");
285 auto eagerInitSingletons = eagerInitSingletons_.rlock();
286 for (
auto*
single : *eagerInitSingletons) {
293 auto state = state_.rlock();
296 throw std::logic_error(
"registrationComplete() not yet called");
300 auto eagerInitSingletons = eagerInitSingletons_.rlock();
302 std::make_shared<std::atomic<size_t>>(eagerInitSingletons->size());
303 for (
auto*
single : *eagerInitSingletons) {
314 if (done !=
nullptr) {
321 if (!
single->creationStarted()) {
329 auto stateW = state_.wlock();
335 auto stateR = stateW.moveFromWriteToRead();
337 auto singletons = singletons_.rlock();
338 auto creationOrder = creationOrder_.rlock();
340 CHECK_GE(singletons->size(), creationOrder->size());
345 for (
auto& singleton_type : *creationOrder) {
346 singletons->at(singleton_type)->preDestroyInstance(deleter);
350 for (
auto type_iter = creationOrder->rbegin();
351 type_iter != creationOrder->rend();
353 singletons->at(*type_iter)->destroyInstance();
356 for (
auto& singleton_type : *creationOrder) {
357 auto instance = singletons->at(singleton_type);
358 if (!instance->hasLiveInstance()) {
362 fatalHelper.leakedSingletons_.push_back(instance->type());
367 auto creationOrder = creationOrder_.wlock();
368 creationOrder->clear();
373 auto state = state_.wlock();
391 #if FOLLY_USE_SYMBOLIZER 402 constexpr
size_t kDefaultCapacity = 500;
410 return printer.
str();
414 struct SetStackTraceGetter {
415 SetStackTraceGetter() {
422 SetStackTraceGetter setStackTraceGetter;
424 SetStackTraceGetter
__attribute__((__init_priority__(101))) setStackTraceGetter;
void registerSingleton(detail::SingletonHolderBase *entry)
void singletonThrowNullCreator(const std::type_info &type)
static SingletonVault * singleton()
static Singleton< ShutdownSocketSet, PrivateTag > singleton
ssize_t getStackTraceSafe(uintptr_t *addresses, size_t maxAddresses)
std::string sformat(StringPiece fmt, Args &&...args)
static void singleton_hs_init_weak(int *argc, char **argv[]) __attribute__((__weakref__("hs_init")))
void singletonWarnCreateUnregisteredAndAbort(const TypeDescriptor &type)
void singletonWarnCreateCircularDependencyAndAbort(const TypeDescriptor &type)
void singletonWarnLeakyInstantiatingNotRegisteredAndAbort(const TypeDescriptor &type)
—— Concurrent Priority Queue Implementation ——
void println(uintptr_t address, const SymbolizedFrame &frame)
static std::atomic< StackTraceGetterPtr > & stackTraceGetter()
void singletonThrowGetInvokedAfterDestruction(const TypeDescriptor &type)
const int kMaxStackTraceDepth
void singletonWarnRegisterMockEarlyAndAbort(const TypeDescriptor &type)
void singletonWarnDoubleRegistrationAndAbort(const TypeDescriptor &type)
std::vector< detail::TypeDescriptor > leakedSingletons_
void singletonWarnDestroyInstanceLeak(const TypeDescriptor &type, const void *ptr)
std::basic_string< E, T, A > toStdString() const
void singletonWarnLeakyDoubleRegistrationAndAbort(const TypeDescriptor &type)
static void scheduleDestroyInstances()
void doEagerInitVia(Executor &exe, folly::Baton<> *done=nullptr)
#define CHECK_THROW(cond, E)
void singletonWarnCreateBeforeRegistrationCompleteAndAbort(const TypeDescriptor &type)
__attribute__((noinline, noclone)) VirtualBase *makeVirtual()
TypeDescriptor type() const
void singletonPrintDestructionStackTrace(const TypeDescriptor &type)
static Type defaultVaultType()
void symbolize(const uintptr_t *addresses, SymbolizedFrame *frames, size_t frameCount)
void registrationComplete()
fbstring demangle(const char *name)
void addEagerInitSingleton(detail::SingletonHolderBase *entry)