extensions: Deterministic global construction ordering

Right now, we have an issue where the global variables owned by
extensions.cpp are not necessarily constructed before other objects try
and use them in their own global constructors. We need to gate access on
functions that guarantee the object is constructed before it is used.

Change-Id: I71f88a901c21b9121a25e3ccd365d2a74a9be709
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/extensions.cpp b/extensions.cpp
index fa68789..2fc8792 100644
--- a/extensions.cpp
+++ b/extensions.cpp
@@ -1,22 +1,39 @@
 #include "extensions.hpp"
 
-// The 'extensions_test' testcase needs to define these itself.
-// Skip over the definition to avoid duplicate symbol definitions.
-#ifndef TESTCASE_extensions_test
-
 namespace phosphor
 {
 namespace logging
 {
 
-StartupFunctions Extensions::startupFunctions{};
-CreateFunctions Extensions::createFunctions{};
-DeleteFunctions Extensions::deleteFunctions{};
-DeleteProhibitedFunctions Extensions::deleteProhibitedFunctions{};
-Extensions::DefaultErrorCaps Extensions::defaultErrorCaps =
-    Extensions::DefaultErrorCaps::enable;
+StartupFunctions& Extensions::getStartupFunctions()
+{
+    static StartupFunctions startupFunctions{};
+    return startupFunctions;
+}
+
+CreateFunctions& Extensions::getCreateFunctions()
+{
+    static CreateFunctions createFunctions{};
+    return createFunctions;
+}
+
+DeleteFunctions& Extensions::getDeleteFunctions()
+{
+    static DeleteFunctions deleteFunctions{};
+    return deleteFunctions;
+}
+
+DeleteProhibitedFunctions& Extensions::getDeleteProhibitedFunctions()
+{
+    static DeleteProhibitedFunctions deleteProhibitedFunctions{};
+    return deleteProhibitedFunctions;
+}
+
+Extensions::DefaultErrorCaps& Extensions::getDefaultErrorCaps()
+{
+    static DefaultErrorCaps defaultErrorCaps = DefaultErrorCaps::enable;
+    return defaultErrorCaps;
+}
 
 } // namespace logging
 } // namespace phosphor
-
-#endif
diff --git a/extensions.hpp b/extensions.hpp
index 4e38f1d..c10e6a0 100644
--- a/extensions.hpp
+++ b/extensions.hpp
@@ -115,7 +115,7 @@
      */
     explicit Extensions(StartupFunction func)
     {
-        startupFunctions.push_back(func);
+        getStartupFunctions().push_back(func);
     }
 
     /**
@@ -128,7 +128,7 @@
      */
     explicit Extensions(CreateFunction func)
     {
-        createFunctions.push_back(func);
+        getCreateFunctions().push_back(func);
     }
 
     /**
@@ -141,7 +141,7 @@
      */
     explicit Extensions(DeleteFunction func)
     {
-        deleteFunctions.push_back(func);
+        getDeleteFunctions().push_back(func);
     }
 
     /**
@@ -155,7 +155,7 @@
      */
     explicit Extensions(DeleteProhibitedFunction func)
     {
-        deleteProhibitedFunctions.push_back(func);
+        getDeleteProhibitedFunctions().push_back(func);
     }
 
     /**
@@ -169,44 +169,38 @@
      */
     explicit Extensions(DefaultErrorCaps defaultCaps)
     {
-        defaultErrorCaps = defaultCaps;
+        getDefaultErrorCaps() = defaultCaps;
     }
 
     /**
      * @brief Returns the Startup functions
      * @return StartupFunctions - the Startup functions
      */
-    static StartupFunctions& getStartupFunctions()
-    {
-        return startupFunctions;
-    }
+    static StartupFunctions& getStartupFunctions();
 
     /**
      * @brief Returns the Create functions
      * @return CreateFunctions - the Create functions
      */
-    static CreateFunctions& getCreateFunctions()
-    {
-        return createFunctions;
-    }
+    static CreateFunctions& getCreateFunctions();
 
     /**
      * @brief Returns the Delete functions
      * @return DeleteFunctions - the Delete functions
      */
-    static DeleteFunctions& getDeleteFunctions()
-    {
-        return deleteFunctions;
-    }
+    static DeleteFunctions& getDeleteFunctions();
 
     /**
      * @brief Returns the DeleteProhibited functions
      * @return DeleteProhibitedFunctions - the DeleteProhibited functions
      */
-    static DeleteProhibitedFunctions& getDeleteProhibitedFunctions()
-    {
-        return deleteProhibitedFunctions;
-    }
+    static DeleteProhibitedFunctions& getDeleteProhibitedFunctions();
+
+    /**
+     * @brief Returns the DefaultErrorCaps value
+     * @return DefaultErrorCaps - the DefaultErrorCaps value
+     */
+    static DefaultErrorCaps& getDefaultErrorCaps();
 
     /**
      * @brief Say if the default log capping policy should be disabled
@@ -214,35 +208,8 @@
      */
     static bool disableDefaultLogCaps()
     {
-        return defaultErrorCaps == DefaultErrorCaps::disable;
+        return getDefaultErrorCaps() == DefaultErrorCaps::disable;
     }
-
-  private:
-    /**
-     * @brief Vector of functions to call on app startup.
-     */
-    static StartupFunctions startupFunctions;
-
-    /**
-     * @brief Vector of functions to call after creating an event log.
-     */
-    static CreateFunctions createFunctions;
-
-    /**
-     * @brief Vector of functions to call after deleting an event log.
-     */
-    static DeleteFunctions deleteFunctions;
-
-    /**
-     * @brief Vector of functions to call to check if deleting a
-     *        particular event log is prohibited.
-     */
-    static DeleteProhibitedFunctions deleteProhibitedFunctions;
-
-    /**
-     * @brief If default log capping should be disabled.
-     */
-    static DefaultErrorCaps defaultErrorCaps;
 };
 
 } // namespace logging
diff --git a/test/extensions_test.cpp b/test/extensions_test.cpp
index 31115af..a3bd119 100644
--- a/test/extensions_test.cpp
+++ b/test/extensions_test.cpp
@@ -7,14 +7,6 @@
 
 using namespace phosphor::logging;
 
-// gtest doesn't like this happening in another file, so do it here.
-StartupFunctions Extensions::startupFunctions{};
-CreateFunctions Extensions::createFunctions{};
-DeleteFunctions Extensions::deleteFunctions{};
-DeleteProhibitedFunctions Extensions::deleteProhibitedFunctions{};
-Extensions::DefaultErrorCaps Extensions::defaultErrorCaps =
-    Extensions::DefaultErrorCaps::enable;
-
 void startup1(internal::Manager& /*manager*/)
 {
 }