/*
- * 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.
#include <folly/Singleton.h>
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+
#include <atomic>
#include <cstdio>
#include <cstdlib>
-#include <sstream>
+#include <iostream>
#include <string>
-#include <folly/FileUtil.h>
#include <folly/ScopeGuard.h>
+#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();
}
-}
+} // namespace detail
namespace {
FatalHelper __attribute__ ((__init_priority__ (101))) fatalHelper;
#endif
-}
+} // namespace
SingletonVault::~SingletonVault() { destroyInstances(); }
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.");
}
}
}
static SingletonVaultDestructor singletonVaultDestructor;
}
-}
+} // namespace folly