diff --git a/src/lib/lifecycle.cpp b/src/lib/lifecycle.cpp index e643505e2..1ac3f07ca 100644 --- a/src/lib/lifecycle.cpp +++ b/src/lib/lifecycle.cpp @@ -37,6 +37,19 @@ using util::cStr; namespace lumiera { + // ==== implementation Lifecycle Registry ======= + + /** @remark since the LifecycleRegistry is used to implement + * the most basic initialisation, we need to ensure it is fully + * initialised and gets up on demand as early as possible. */ + LifecycleRegistry& + LifecycleRegistry::instance() + { + static LifecycleRegistry theRegistry; + return theRegistry; // Meyer's singleton + } + + // ==== implementation LifecycleHook class ======= diff --git a/src/lib/lifecycleregistry.hpp b/src/lib/lifecycleregistry.hpp index eb3865af9..50f8947c3 100644 --- a/src/lib/lifecycleregistry.hpp +++ b/src/lib/lifecycleregistry.hpp @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -53,7 +52,6 @@ namespace lumiera { using boost::noncopyable; using util::contains; - using std::unique_ptr; using std::function; using std::string; @@ -94,12 +92,7 @@ namespace lumiera { /** get the (single) LifecycleRegistry instance. * @warning don't use it after the end of main()! */ - static LifecycleRegistry& instance() // Meyer's singleton - { - static unique_ptr theRegistry_; - if (!theRegistry_) theRegistry_.reset (new LifecycleRegistry ()); - return *theRegistry_; - } + static LifecycleRegistry& instance(); private: @@ -110,7 +103,6 @@ namespace lumiera { } ~LifecycleRegistry () { } - friend class std::default_delete; }; diff --git a/src/lib/symbol-impl.cpp b/src/lib/symbol-impl.cpp index b5d2797a5..c616ce7c2 100644 --- a/src/lib/symbol-impl.cpp +++ b/src/lib/symbol-impl.cpp @@ -60,7 +60,12 @@ namespace lib { namespace { // global symbol table - SymbolTable symbolTable; + SymbolTable& + symbolTable() + { + static SymbolTable theSymbolTable; + return theSymbolTable; // Meyer's Singleton + } } @@ -68,9 +73,11 @@ namespace lib { * create Symbol by symbol table lookup. * @note identical strings will be mapped to the same Symbol (embedded pointer) * @warning potential lock contention, since each ctor call needs to do a lookup + * @remark since lumiera::LifecycleHook entries use a Symbol, the symbol table is + * implemented as Meyer's singleton and pulled up early, way before main() */ Symbol::Symbol (string&& definition) - : Literal{symbolTable.internedString (forward (definition))} + : Literal{symbolTable().internedString (forward (definition))} { } diff --git a/src/proc/control/command-setup.cpp b/src/proc/control/command-setup.cpp index dc8645bc5..4ad3e4d06 100644 --- a/src/proc/control/command-setup.cpp +++ b/src/proc/control/command-setup.cpp @@ -69,7 +69,12 @@ namespace control { using CmdDefEntry = std::tuple; - std::deque pendingCmdDefinitions; + std::deque& + pendingCmdDefinitions() + { + static std::deque definitionQueue; + return definitionQueue; + } }//(End) implementation details @@ -119,7 +124,7 @@ namespace control { throw error::Invalid ("unbound function/closure provided for CommandSetup" , error::LUMIERA_ERROR_BOTTOM_VALUE); - pendingCmdDefinitions.emplace_front (cmdID_, move(definitionBlock)); + pendingCmdDefinitions().emplace_front (cmdID_, move(definitionBlock)); return *this; } @@ -127,22 +132,22 @@ namespace control { size_t CommandSetup::pendingCnt() { - return pendingCmdDefinitions.size(); + return pendingCmdDefinitions().size(); } void CommandSetup::invokeDefinitionClosures() { - while (not pendingCmdDefinitions.empty()) + while (not pendingCmdDefinitions().empty()) { - CmdDefEntry& entry = pendingCmdDefinitions.back(); + CmdDefEntry& entry = pendingCmdDefinitions().back(); Symbol& cmdID{get(entry)}; DefinitionClosure& buildDefinition{get (entry)}; TRACE (command, "defining Command(%s)...", cmdID.c()); CommandDef def(cmdID); buildDefinition(def); - pendingCmdDefinitions.pop_back(); + pendingCmdDefinitions().pop_back(); } }