From fbbef9621fdcd9663e16ff50883eb67b63c859a1 Mon Sep 17 00:00:00 2001
From: Joscha Schmiedt <joscha@schmiedt.dev>
Date: Fri, 13 Sep 2024 21:33:58 +0200
Subject: [PATCH] Move static singletons to namespace level

The singleton instances of ConfigurationManager and ConnectionManager
were stored as static variables in the static GetInstance methods.

This causes weird errors on Windows where the singleton instance is not
initialized in time and remains empty. This could be due to
undefined behavior?

Moving them to the namespace level fixes the unit test errors.
---
 include/linkahead/configuration.h | 7 +++----
 include/linkahead/connection.h    | 8 ++++----
 src/linkahead/configuration.cpp   | 5 +++++
 src/linkahead/connection.cpp      | 7 +++++++
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/include/linkahead/configuration.h b/include/linkahead/configuration.h
index 06754cf..a25727d 100644
--- a/include/linkahead/configuration.h
+++ b/include/linkahead/configuration.h
@@ -103,10 +103,8 @@ public:
  */
 class ConfigurationManager {
 public:
-  static ConfigurationManager &GetInstance() {
-    static ConfigurationManager instance;
-    return instance;
-  };
+  static ConfigurationManager &GetInstance();
+  ;
 
   /**
    * See mReset.
@@ -156,6 +154,7 @@ public:
 private:
   Arena arena;
   JsonValue json_configuration;
+  static ConfigurationManager mInstance;
 
   inline ConfigurationManager()
     : json_configuration(nullptr){
diff --git a/include/linkahead/connection.h b/include/linkahead/connection.h
index 844f46a..aca0966 100644
--- a/include/linkahead/connection.h
+++ b/include/linkahead/connection.h
@@ -170,6 +170,9 @@ class ConnectionManager {
 private:
   mutable std::map<std::string, std::shared_ptr<Connection>> connections;
   mutable std::string default_connection_name;
+
+  static ConnectionManager instance;
+
   inline ConnectionManager(){};
 
   auto mHasConnection(const std::string &name) const -> bool;
@@ -184,10 +187,7 @@ private:
   }
 
 public:
-  static ConnectionManager &GetInstance() {
-    static ConnectionManager instance;
-    return instance;
-  };
+  static ConnectionManager &GetInstance();
 
   inline static auto HasConnection(const std::string &name) -> bool {
     return ConnectionManager::GetInstance().mHasConnection(name);
diff --git a/src/linkahead/configuration.cpp b/src/linkahead/configuration.cpp
index 8db1f79..f8074ba 100644
--- a/src/linkahead/configuration.cpp
+++ b/src/linkahead/configuration.cpp
@@ -70,6 +70,9 @@
   }
 
 namespace linkahead::configuration {
+
+ConfigurationManager ConfigurationManager::mInstance;
+
 using boost::json::object;
 using boost::json::value;
 using grpc::InsecureChannelCredentials;
@@ -424,6 +427,8 @@ auto ConfigurationManager::mGetDefaultConnectionName() const -> std::string {
   throw ConfigurationError("Could not determine the default connection.");
 }
 
+inline ConfigurationManager &ConfigurationManager::GetInstance() { return mInstance; }
+
 // TODO(tf) This has apparently a cognitive complexity of 34>25 (threshold).
 auto ConfigurationManager::InitializeDefaults() -> int { // NOLINT
 
diff --git a/src/linkahead/connection.cpp b/src/linkahead/connection.cpp
index 91d5a0c..373b367 100644
--- a/src/linkahead/connection.cpp
+++ b/src/linkahead/connection.cpp
@@ -66,6 +66,13 @@ using linkahead::info::VersionInfo;
 using linkahead::transaction::Transaction;
 using linkahead::transaction::TransactionStatus;
 
+
+ConnectionManager ConnectionManager::instance;
+
+ConnectionManager &ConnectionManager::GetInstance() {
+  return instance;
+}
+
 Connection::Connection(const ConnectionConfiguration &configuration) {
   const std::string target =
     configuration.GetHost() + ":" + std::to_string(configuration.GetPort());
-- 
GitLab