apply clang-tidy modernize-use-override
[folly.git] / folly / Singleton.cpp
index 5e89442c01e0a2692b10fe5e38e0c306a0c9c0e9..7d3eeac61cf377d8cce358251c227c48ddfd2e7d 100644 (file)
@@ -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.
 
 #include <folly/Singleton.h>
 
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+
 #include <atomic>
 #include <cstdio>
 #include <cstdlib>
 
 #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(
@@ -103,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.");
       }
     }
   }