diff options
author | Henrik Edin <henrik.edin@mongodb.com> | 2018-02-27 09:47:29 -0500 |
---|---|---|
committer | Henrik Edin <henrik.edin@mongodb.com> | 2018-03-12 10:57:28 -0400 |
commit | 0486c9ff50402c8680d14a495c2d9dfe543939a1 (patch) | |
tree | ae6959309757d62c055a2f6cecbc8532aba17400 /src/mongo/base/initializer.cpp | |
parent | d7012b42d747b498dc06747240c79f576425bbc6 (diff) | |
download | mongo-0486c9ff50402c8680d14a495c2d9dfe543939a1.tar.gz |
SERVER-33629 Deinitialization support for MONGO_INITIALIZER. Done via the GlobalInitializerRegisterer instead of macros. Deinitialization executes in reverse order from initialization.
Diffstat (limited to 'src/mongo/base/initializer.cpp')
-rw-r--r-- | src/mongo/base/initializer.cpp | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/src/mongo/base/initializer.cpp b/src/mongo/base/initializer.cpp index 8de4eb41533..9939057b070 100644 --- a/src/mongo/base/initializer.cpp +++ b/src/mongo/base/initializer.cpp @@ -27,6 +27,7 @@ #include "mongo/base/initializer.h" +#include "mongo/base/deinitializer_context.h" #include "mongo/base/global_initializer.h" #include "mongo/util/assert_util.h" #include "mongo/util/quick_exit.h" @@ -37,8 +38,8 @@ namespace mongo { Initializer::Initializer() {} Initializer::~Initializer() {} -Status Initializer::execute(const InitializerContext::ArgumentVector& args, - const InitializerContext::EnvironmentMap& env) const { +Status Initializer::executeInitializers(const InitializerContext::ArgumentVector& args, + const InitializerContext::EnvironmentMap& env) { std::vector<std::string> sortedNodes; Status status = _graph.topSort(&sortedNodes); if (Status::OK() != status) @@ -47,7 +48,14 @@ Status Initializer::execute(const InitializerContext::ArgumentVector& args, InitializerContext context(args, env); for (size_t i = 0; i < sortedNodes.size(); ++i) { - InitializerFunction fn = _graph.getInitializerFunction(sortedNodes[i]); + InitializerDependencyNode* node = _graph.getInitializerNode(sortedNodes[i]); + + // If already initialized then this node is a legacy initializer without re-initialization + // support. + if (node->isInitialized()) + continue; + + auto const& fn = node->getInitializerFunction(); if (!fn) { return Status(ErrorCodes::InternalError, "topSort returned a node that has no associated function: \"" + @@ -61,13 +69,43 @@ Status Initializer::execute(const InitializerContext::ArgumentVector& args, if (Status::OK() != status) return status; + + node->setInitialized(true); + } + return Status::OK(); +} + +Status Initializer::executeDeinitializers() { + std::vector<std::string> sortedNodes; + Status status = _graph.topSort(&sortedNodes); + if (Status::OK() != status) + return status; + + DeinitializerContext context; + + // Execute deinitialization in reverse order from initialization. + for (auto it = sortedNodes.rbegin(), end = sortedNodes.rend(); it != end; ++it) { + InitializerDependencyNode* node = _graph.getInitializerNode(*it); + auto const& fn = node->getDeinitializerFunction(); + if (fn) { + try { + status = fn(&context); + } catch (const DBException& xcp) { + return xcp.toStatus(); + } + + if (Status::OK() != status) + return status; + + node->setInitialized(false); + } } return Status::OK(); } Status runGlobalInitializers(const InitializerContext::ArgumentVector& args, const InitializerContext::EnvironmentMap& env) { - return getGlobalInitializer().execute(args, env); + return getGlobalInitializer().executeInitializers(args, env); } Status runGlobalInitializers(int argc, const char* const* argv, const char* const* envp) { @@ -89,6 +127,10 @@ Status runGlobalInitializers(int argc, const char* const* argv, const char* cons return runGlobalInitializers(args, env); } +Status runGlobalDeinitializers() { + return getGlobalInitializer().executeDeinitializers(); +} + void runGlobalInitializersOrDie(int argc, const char* const* argv, const char* const* envp) { Status status = runGlobalInitializers(argc, argv, envp); if (!status.isOK()) { |