summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2018-03-12 11:14:15 -0400
committerHenrik Edin <henrik.edin@mongodb.com>2018-03-26 15:54:16 -0400
commitaf600c3876a26f62d8dde93bf769fc4ca3054072 (patch)
treeecef32a9b3c6c54501651168cce48093e76e9858 /src/mongo/db
parent2676a176759359c8614c0e37b267198259b6789f (diff)
downloadmongo-af600c3876a26f62d8dde93bf769fc4ca3054072.tar.gz
SERVER-30170 Embedded can now shutdown and re-initialize.
- ServiceContext* is now closer to be an instance context for the database. We still don't support multiple instances but I wrote the new code with this in mind. Teardown and reinitialize then becomes a matter of being able to delete and re-create the ServiceContext*. - Use the new MONGO_INITIALIZER that supports deinit/reinit to be able to re-initialize global systems that are decorations on ServiceContext. - Move creation/destruction of ServiceContext* out of MONGO_INITIALIZER. This so we can hold an exclusive lock during as much as possible of the shutdown (like how mongod does) - New ServiceContext registrer where we can link in different implementations of ServiceContext (replaces the SetGlobalEnvironment MONGO_INITIALIZER) - As a result the SetGlobalEnvironment prerequisite for MONGO_INITIALIZERs is gone. - The ServiceContext is passed to runGlobalInitializers, put in InitializationContext/DeinitializationContext so the initializers know which context they operate on.
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/auth/auth_decorations.cpp5
-rw-r--r--src/mongo/db/auth/authorization_manager_global.cpp34
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry.cpp28
-rw-r--r--src/mongo/db/catalog/database_holder_impl.cpp22
-rw-r--r--src/mongo/db/db.cpp7
-rw-r--r--src/mongo/db/pipeline/document_source_sample_test.cpp1
-rw-r--r--src/mongo/db/query/collation/collator_factory_icu_decoration.cpp2
-rw-r--r--src/mongo/db/query/datetime/init_timezone_data.cpp4
-rw-r--r--src/mongo/db/repl/service_context_repl_mock_init.cpp11
-rw-r--r--src/mongo/db/service_context.cpp10
-rw-r--r--src/mongo/db/service_context_d.cpp20
-rw-r--r--src/mongo/db/service_context_fwd.h35
-rw-r--r--src/mongo/db/service_context_noop_init.cpp8
-rw-r--r--src/mongo/db/service_context_registrar.cpp54
-rw-r--r--src/mongo/db/service_context_registrar.h48
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp11
-rw-r--r--src/mongo/db/storage/devnull/devnull_init.cpp4
-rw-r--r--src/mongo/db/storage/encryption_hooks.cpp2
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp2
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp2
-rw-r--r--src/mongo/db/storage/mobile/mobile_init.cpp12
-rw-r--r--src/mongo/db/storage/storage_engine.h11
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp11
27 files changed, 253 insertions, 98 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 99287b19945..1cc6e1ba889 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -470,6 +470,7 @@ env.Library(
'operation_context_group.cpp',
'service_context.cpp',
'service_context_noop.cpp',
+ 'service_context_registrar.cpp',
'unclean_shutdown.cpp',
],
LIBDEPS=[
diff --git a/src/mongo/db/auth/auth_decorations.cpp b/src/mongo/db/auth/auth_decorations.cpp
index bf1b31ca148..b0c1e79f4a9 100644
--- a/src/mongo/db/auth/auth_decorations.cpp
+++ b/src/mongo/db/auth/auth_decorations.cpp
@@ -86,10 +86,7 @@ AuthorizationManager* AuthorizationManager::get(ServiceContext& service) {
void AuthorizationManager::set(ServiceContext* service,
std::unique_ptr<AuthorizationManager> authzManager) {
- auto& manager = getAuthorizationManager(service);
- invariant(authzManager);
- invariant(!manager);
- manager = std::move(authzManager);
+ getAuthorizationManager(service) = std::move(authzManager);
service->registerClientObserver(stdx::make_unique<AuthzClientObserver>());
}
diff --git a/src/mongo/db/auth/authorization_manager_global.cpp b/src/mongo/db/auth/authorization_manager_global.cpp
index 3172d7e1626..39505fab014 100644
--- a/src/mongo/db/auth/authorization_manager_global.cpp
+++ b/src/mongo/db/auth/authorization_manager_global.cpp
@@ -90,20 +90,24 @@ AuthorizationManager* getGlobalAuthorizationManager() {
MONGO_EXPORT_STARTUP_SERVER_PARAMETER(startupAuthSchemaValidation, bool, true);
-MONGO_INITIALIZER_WITH_PREREQUISITES(CreateAuthorizationManager,
- ("SetupInternalSecurityUser",
- "OIDGeneration",
- "SetGlobalEnvironment",
- "CreateAuthorizationExternalStateFactory",
- "EndStartupOptionStorage"))
-(InitializerContext* context) {
- auto authzManager =
- stdx::make_unique<AuthorizationManager>(AuthzManagerExternalState::create());
- authzManager->setAuthEnabled(serverGlobalParams.authState ==
- ServerGlobalParams::AuthState::kEnabled);
- authzManager->setShouldValidateAuthSchemaOnStartup(startupAuthSchemaValidation);
- AuthorizationManager::set(getGlobalServiceContext(), std::move(authzManager));
- return Status::OK();
-}
+GlobalInitializerRegisterer authorizationManagerInitializer(
+ "CreateAuthorizationManager",
+ {"SetupInternalSecurityUser",
+ "OIDGeneration",
+ "CreateAuthorizationExternalStateFactory",
+ "EndStartupOptionStorage"},
+ [](InitializerContext* context) {
+ auto authzManager =
+ stdx::make_unique<AuthorizationManager>(AuthzManagerExternalState::create());
+ authzManager->setAuthEnabled(serverGlobalParams.authState ==
+ ServerGlobalParams::AuthState::kEnabled);
+ authzManager->setShouldValidateAuthSchemaOnStartup(startupAuthSchemaValidation);
+ AuthorizationManager::set(context->serviceContext(), std::move(authzManager));
+ return Status::OK();
+ },
+ [](DeinitializerContext* context) {
+ AuthorizationManager::set(context->serviceContext(), nullptr);
+ return Status::OK();
+ });
} // namespace mongo
diff --git a/src/mongo/db/auth/sasl_mechanism_registry.cpp b/src/mongo/db/auth/sasl_mechanism_registry.cpp
index b46ba9978f3..1572acb2794 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry.cpp
+++ b/src/mongo/db/auth/sasl_mechanism_registry.cpp
@@ -164,16 +164,22 @@ bool SASLServerMechanismRegistry::_mechanismSupportedByConfig(StringData mechNam
return sequenceContains(saslGlobalParams.authenticationMechanisms, mechName);
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(CreateSASLServerMechanismRegistry, ("SetGlobalEnvironment"))
-(::mongo::InitializerContext* context) {
- if (saslGlobalParams.hostName.empty())
- saslGlobalParams.hostName = getHostNameCached();
- if (saslGlobalParams.serviceName.empty())
- saslGlobalParams.serviceName = "mongodb";
-
- auto registry = stdx::make_unique<SASLServerMechanismRegistry>();
- SASLServerMechanismRegistry::set(getGlobalServiceContext(), std::move(registry));
- return Status::OK();
-}
+GlobalInitializerRegisterer SASLServerMechanismRegistryInitializer(
+ "CreateSASLServerMechanismRegistry",
+ [](InitializerContext* context) {
+ if (saslGlobalParams.hostName.empty())
+ saslGlobalParams.hostName = getHostNameCached();
+ if (saslGlobalParams.serviceName.empty())
+ saslGlobalParams.serviceName = "mongodb";
+
+ auto registry = stdx::make_unique<SASLServerMechanismRegistry>();
+ SASLServerMechanismRegistry::set(context->serviceContext(), std::move(registry));
+ return Status::OK();
+ },
+ [](DeinitializerContext* context) {
+ SASLServerMechanismRegistry::set(context->serviceContext(), nullptr);
+
+ return Status::OK();
+ });
} // namespace mongo
diff --git a/src/mongo/db/catalog/database_holder_impl.cpp b/src/mongo/db/catalog/database_holder_impl.cpp
index 1c999013e33..d5b5560df67 100644
--- a/src/mongo/db/catalog/database_holder_impl.cpp
+++ b/src/mongo/db/catalog/database_holder_impl.cpp
@@ -51,16 +51,24 @@
namespace mongo {
namespace {
+DatabaseHolder* _dbHolder = nullptr;
+
DatabaseHolder& dbHolderImpl() {
- static DatabaseHolder _dbHolder;
- return _dbHolder;
+ return *_dbHolder;
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(InitializeDbHolderimpl, ("InitializeDatabaseHolderFactory"))
-(InitializerContext* const) {
- registerDbHolderImpl(dbHolderImpl);
- return Status::OK();
-}
+GlobalInitializerRegisterer dbHolderImplInitializer("InitializeDbHolderimpl",
+ {"InitializeDatabaseHolderFactory"},
+ [](InitializerContext* const) {
+ _dbHolder = new DatabaseHolder();
+ registerDbHolderImpl(dbHolderImpl);
+ return Status::OK();
+ },
+ [](DeinitializerContext* const) {
+ delete _dbHolder;
+ _dbHolder = nullptr;
+ return Status::OK();
+ });
MONGO_INITIALIZER(InitializeDatabaseHolderFactory)(InitializerContext* const) {
DatabaseHolder::registerFactory([] { return stdx::make_unique<DatabaseHolderImpl>(); });
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index cacb7f941a3..beb87a5d086 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -118,6 +118,7 @@
#include "mongo/db/server_parameters.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_d.h"
+#include "mongo/db/service_context_registrar.h"
#include "mongo/db/service_entry_point_mongod.h"
#include "mongo/db/session_catalog.h"
#include "mongo/db/session_killer.h"
@@ -757,8 +758,7 @@ auto makeReplicationExecutor(ServiceContext* serviceContext) {
"NetworkInterfaceASIO-Replication", nullptr, std::move(hookList)));
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(CreateReplicationManager,
- ("SetGlobalEnvironment", "SSLManager", "default"))
+MONGO_INITIALIZER_WITH_PREREQUISITES(CreateReplicationManager, ("SSLManager", "default"))
(InitializerContext* context) {
auto serviceContext = getGlobalServiceContext();
repl::StorageInterface::set(serviceContext, stdx::make_unique<repl::StorageInterfaceImpl>());
@@ -958,7 +958,8 @@ int mongoDbMain(int argc, char* argv[], char** envp) {
srand(static_cast<unsigned>(curTimeMicros64()));
- Status status = mongo::runGlobalInitializers(argc, argv, envp);
+ setGlobalServiceContext(createServiceContext());
+ Status status = mongo::runGlobalInitializers(argc, argv, envp, getGlobalServiceContext());
if (!status.isOK()) {
severe(LogComponent::kControl) << "Failed global initialization: " << status;
quickExit(EXIT_FAILURE);
diff --git a/src/mongo/db/pipeline/document_source_sample_test.cpp b/src/mongo/db/pipeline/document_source_sample_test.cpp
index c1c85924c50..439e0ce3e36 100644
--- a/src/mongo/db/pipeline/document_source_sample_test.cpp
+++ b/src/mongo/db/pipeline/document_source_sample_test.cpp
@@ -40,7 +40,6 @@
#include "mongo/db/pipeline/document_source_sample_from_random_cursor.h"
#include "mongo/db/pipeline/document_value_test_util.h"
#include "mongo/db/pipeline/expression_context.h"
-#include "mongo/db/service_context.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/death_test.h"
#include "mongo/unittest/unittest.h"
diff --git a/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp b/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp
index 46ddbf54d8b..e37ce036511 100644
--- a/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp
+++ b/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp
@@ -37,7 +37,7 @@ namespace mongo {
namespace {
-MONGO_INITIALIZER_WITH_PREREQUISITES(CreateCollatorFactory, ("SetGlobalEnvironment", "LoadICUData"))
+MONGO_INITIALIZER_WITH_PREREQUISITES(CreateCollatorFactory, ("LoadICUData"))
(InitializerContext* context) {
CollatorFactoryInterface::set(getGlobalServiceContext(),
stdx::make_unique<CollatorFactoryICU>());
diff --git a/src/mongo/db/query/datetime/init_timezone_data.cpp b/src/mongo/db/query/datetime/init_timezone_data.cpp
index b86159e3976..0c17cca0457 100644
--- a/src/mongo/db/query/datetime/init_timezone_data.cpp
+++ b/src/mongo/db/query/datetime/init_timezone_data.cpp
@@ -39,8 +39,8 @@
namespace mongo {
-MONGO_INITIALIZER_WITH_PREREQUISITES(
- LoadTimeZoneDB, ("GlobalLogManager", "SetGlobalEnvironment", "EndStartupOptionStorage"))
+MONGO_INITIALIZER_WITH_PREREQUISITES(LoadTimeZoneDB,
+ ("GlobalLogManager", "EndStartupOptionStorage"))
(InitializerContext* context) {
auto serviceContext = getGlobalServiceContext();
if (!serverGlobalParams.timeZoneInfoPath.empty()) {
diff --git a/src/mongo/db/repl/service_context_repl_mock_init.cpp b/src/mongo/db/repl/service_context_repl_mock_init.cpp
index 720457b3469..c35b47f61d7 100644
--- a/src/mongo/db/repl/service_context_repl_mock_init.cpp
+++ b/src/mongo/db/repl/service_context_repl_mock_init.cpp
@@ -31,17 +31,18 @@
#include "mongo/base/init.h"
#include "mongo/db/repl/service_context_repl_mock.h"
#include "mongo/db/service_context.h"
-#include "mongo/stdx/memory.h"
+#include "mongo/db/service_context_registrar.h"
#include "mongo/util/clock_source_mock.h"
+#include <memory>
+
namespace mongo {
namespace repl {
namespace {
-MONGO_INITIALIZER(SetGlobalEnvironment)(InitializerContext* context) {
- setGlobalServiceContext(stdx::make_unique<ServiceContextReplMock>());
- return Status::OK();
-}
+ServiceContextRegistrar serviceContextCreator([]() {
+ return std::make_unique<ServiceContextReplMock>();
+});
} // namespace
} // namespace repl
diff --git a/src/mongo/db/service_context.cpp b/src/mongo/db/service_context.cpp
index 48004bf0174..b3392b684bc 100644
--- a/src/mongo/db/service_context.cpp
+++ b/src/mongo/db/service_context.cpp
@@ -69,9 +69,13 @@ ServiceContext* waitAndGetGlobalServiceContext() {
}
void setGlobalServiceContext(std::unique_ptr<ServiceContext>&& serviceContext) {
- fassert(17509, serviceContext.get());
-
- delete globalServiceContext;
+ if (globalServiceContext) {
+ // Make sure that calling getGlobalServiceContext() during the destructor results in
+ // nullptr. Decorations might try and do this.
+ auto oldServiceContext = globalServiceContext;
+ globalServiceContext = nullptr;
+ delete oldServiceContext;
+ }
stdx::lock_guard<stdx::mutex> lk(globalServiceContextMutex);
diff --git a/src/mongo/db/service_context_d.cpp b/src/mongo/db/service_context_d.cpp
index 3dad551125c..95459a6e41e 100644
--- a/src/mongo/db/service_context_d.cpp
+++ b/src/mongo/db/service_context_d.cpp
@@ -37,6 +37,7 @@
#include "mongo/db/client.h"
#include "mongo/db/concurrency/lock_state.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context_registrar.h"
#include "mongo/db/service_entry_point_mongod.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/db/storage/storage_engine_lock_file.h"
@@ -53,19 +54,14 @@
namespace mongo {
namespace {
-auto makeMongoDServiceContext() {
- auto service = stdx::make_unique<ServiceContextMongoD>();
- service->setServiceEntryPoint(stdx::make_unique<ServiceEntryPointMongod>(service.get()));
- service->setTickSource(stdx::make_unique<SystemTickSource>());
- service->setFastClockSource(stdx::make_unique<SystemClockSource>());
- service->setPreciseClockSource(stdx::make_unique<SystemClockSource>());
+ServiceContextRegistrar serviceContextCreator([]() {
+ auto service = std::make_unique<ServiceContextMongoD>();
+ service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service.get()));
+ service->setTickSource(std::make_unique<SystemTickSource>());
+ service->setFastClockSource(std::make_unique<SystemClockSource>());
+ service->setPreciseClockSource(std::make_unique<SystemClockSource>());
return service;
-}
-
-MONGO_INITIALIZER(SetGlobalEnvironment)(InitializerContext* context) {
- setGlobalServiceContext(makeMongoDServiceContext());
- return Status::OK();
-}
+});
} // namespace
extern bool _supportsDocLocking;
diff --git a/src/mongo/db/service_context_fwd.h b/src/mongo/db/service_context_fwd.h
new file mode 100644
index 00000000000..48c36da674f
--- /dev/null
+++ b/src/mongo/db/service_context_fwd.h
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2018 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+namespace mongo {
+
+class ServiceContext;
+
+} // namespace mongo
diff --git a/src/mongo/db/service_context_noop_init.cpp b/src/mongo/db/service_context_noop_init.cpp
index 8c66da1bd5a..27e4306ad49 100644
--- a/src/mongo/db/service_context_noop_init.cpp
+++ b/src/mongo/db/service_context_noop_init.cpp
@@ -31,16 +31,16 @@
#include "mongo/base/init.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_registrar.h"
#include "mongo/stdx/memory.h"
namespace mongo {
namespace {
-MONGO_INITIALIZER(SetGlobalEnvironment)(InitializerContext* context) {
- setGlobalServiceContext(stdx::make_unique<ServiceContextNoop>());
- return Status::OK();
-}
+ServiceContextRegistrar serviceContextEmbeddedFactory([]() {
+ return std::make_unique<ServiceContextNoop>();
+});
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/service_context_registrar.cpp b/src/mongo/db/service_context_registrar.cpp
new file mode 100644
index 00000000000..26aa48ac15b
--- /dev/null
+++ b/src/mongo/db/service_context_registrar.cpp
@@ -0,0 +1,54 @@
+/**
+* Copyright (C) 2018 MongoDB Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects for
+* all of the code used other than as permitted herein. If you modify file(s)
+* with this exception, you may extend this exception to your version of the
+* file(s), but you are not obligated to do so. If you do not wish to do so,
+* delete this exception statement from your version. If you delete this
+* exception statement from all source files in the program, then also delete
+* it in the license file.
+*/
+
+#include "mongo/db/service_context_registrar.h"
+
+#include "mongo/db/service_context.h"
+
+namespace mongo {
+namespace {
+std::function<std::unique_ptr<ServiceContext>()>& getServiceContextFactory() {
+ static std::function<std::unique_ptr<ServiceContext>()> factory;
+ return factory;
+}
+}
+
+ServiceContextRegistrar::ServiceContextRegistrar(
+ std::function<std::unique_ptr<ServiceContext>()> fn) {
+ invariant(!hasServiceContextFactory());
+ getServiceContextFactory() = std::move(fn);
+}
+
+bool hasServiceContextFactory() {
+ return getServiceContextFactory() ? true : false;
+}
+
+std::unique_ptr<ServiceContext> createServiceContext() {
+ return getServiceContextFactory()();
+}
+} // namespace mongo
diff --git a/src/mongo/db/service_context_registrar.h b/src/mongo/db/service_context_registrar.h
new file mode 100644
index 00000000000..2317d8862f6
--- /dev/null
+++ b/src/mongo/db/service_context_registrar.h
@@ -0,0 +1,48 @@
+/**
+* Copyright (C) 2018 MongoDB Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects for
+* all of the code used other than as permitted herein. If you modify file(s)
+* with this exception, you may extend this exception to your version of the
+* file(s), but you are not obligated to do so. If you do not wish to do so,
+* delete this exception statement from your version. If you delete this
+* exception statement from all source files in the program, then also delete
+* it in the license file.
+*/
+
+#pragma once
+
+#include <functional>
+#include <memory>
+
+namespace mongo {
+class ServiceContext;
+
+// This is a initialization registration system similar to MONGO_INITIALIZER. But it cannot be an
+// MONGO_INITIALIZER because we need to create the service context before the MONGO_INITIALIZERS
+// execute. This class should probably be refactored to use the shim system from this ticket:
+// https://jira.mongodb.org/browse/SERVER-32645
+class ServiceContextRegistrar {
+public:
+ explicit ServiceContextRegistrar(std::function<std::unique_ptr<ServiceContext>()> fn);
+};
+
+bool hasServiceContextFactory();
+std::unique_ptr<ServiceContext> createServiceContext();
+} // namespace mongo
diff --git a/src/mongo/db/sorter/sorter_test.cpp b/src/mongo/db/sorter/sorter_test.cpp
index 6a85cbfaef2..3ba4e8a98c3 100644
--- a/src/mongo/db/sorter/sorter_test.cpp
+++ b/src/mongo/db/sorter/sorter_test.cpp
@@ -38,7 +38,7 @@
#include "mongo/config.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_noop.h"
-#include "mongo/stdx/memory.h"
+#include "mongo/db/service_context_registrar.h"
#include "mongo/stdx/thread.h"
#include "mongo/unittest/temp_dir.h"
#include "mongo/unittest/unittest.h"
@@ -47,6 +47,8 @@
// Need access to internal classes
#include "mongo/db/sorter/sorter.cpp"
+#include <memory>
+
namespace mongo {
using namespace mongo::sorter;
using std::make_shared;
@@ -55,10 +57,9 @@ using std::pair;
namespace {
// Stub to avoid including the server environment library.
-MONGO_INITIALIZER(SetGlobalEnvironment)(InitializerContext* context) {
- setGlobalServiceContext(stdx::make_unique<ServiceContextNoop>());
- return Status::OK();
-}
+ServiceContextRegistrar serviceContextCreator([]() {
+ return std::make_unique<ServiceContextNoop>();
+});
} // namespace
//
diff --git a/src/mongo/db/storage/devnull/devnull_init.cpp b/src/mongo/db/storage/devnull/devnull_init.cpp
index 7403a5d2fb9..dff10077427 100644
--- a/src/mongo/db/storage/devnull/devnull_init.cpp
+++ b/src/mongo/db/storage/devnull/devnull_init.cpp
@@ -1,5 +1,3 @@
-// devnull_init.cpp
-
/**
* Copyright (C) 2014 MongoDB Inc.
*
@@ -66,7 +64,7 @@ public:
};
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(DevNullEngineInit, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(DevNullEngineInit)
(InitializerContext* context) {
getGlobalServiceContext()->registerStorageEngine("devnull", new DevNullStorageEngineFactory());
return Status::OK();
diff --git a/src/mongo/db/storage/encryption_hooks.cpp b/src/mongo/db/storage/encryption_hooks.cpp
index 9ee9a317dbe..8a81d20dd2d 100644
--- a/src/mongo/db/storage/encryption_hooks.cpp
+++ b/src/mongo/db/storage/encryption_hooks.cpp
@@ -41,7 +41,7 @@
namespace mongo {
/* Make a EncryptionHooks pointer a decoration on the global ServiceContext */
-MONGO_INITIALIZER_WITH_PREREQUISITES(SetEncryptionHooks, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(SetEncryptionHooks)
(InitializerContext* context) {
auto encryptionHooks = stdx::make_unique<EncryptionHooks>();
EncryptionHooks::set(getGlobalServiceContext(), std::move(encryptionHooks));
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp
index df936cfacb8..b52507c20df 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp
@@ -72,7 +72,7 @@ public:
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(EphemeralForTestEngineInit, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(EphemeralForTestEngineInit)
(InitializerContext* context) {
getGlobalServiceContext()->registerStorageEngine("ephemeralForTest",
new EphemeralForTestFactory());
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp
index 10eb30243f4..08f586f2035 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp
@@ -76,7 +76,7 @@ public:
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(MMAPV1EngineInit, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(MMAPV1EngineInit)
(InitializerContext* context) {
getGlobalServiceContext()->registerStorageEngine("mmapv1", new MMAPV1Factory());
return Status::OK();
diff --git a/src/mongo/db/storage/mobile/mobile_init.cpp b/src/mongo/db/storage/mobile/mobile_init.cpp
index 08d078cd2fc..c9d895d0332 100644
--- a/src/mongo/db/storage/mobile/mobile_init.cpp
+++ b/src/mongo/db/storage/mobile/mobile_init.cpp
@@ -70,10 +70,12 @@ public:
};
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(MobileKVEngineInit, ("SetGlobalEnvironment"))
-(InitializerContext* context) {
- getGlobalServiceContext()->registerStorageEngine("mobile", new MobileFactory());
- return Status::OK();
-}
+GlobalInitializerRegisterer mobileKVEngineInitializer(
+ "MobileKVEngineInit",
+ [](InitializerContext* context) {
+ context->serviceContext()->registerStorageEngine("mobile", new MobileFactory());
+ return Status::OK();
+ },
+ [](DeinitializerContext* const) { return Status::OK(); });
} // namespace mongo
diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h
index 486360ba35d..fc2d9d99a08 100644
--- a/src/mongo/db/storage/storage_engine.h
+++ b/src/mongo/db/storage/storage_engine.h
@@ -139,6 +139,11 @@ public:
};
/**
+ * The destructor should only be called if we are tearing down but not exiting the process.
+ */
+ virtual ~StorageEngine() {}
+
+ /**
* Called after the globalStorageEngine pointer has been set up, before any other methods
* are called. Any initialization work that requires the ability to create OperationContexts
* should be done here rather than in the constructor.
@@ -389,12 +394,6 @@ public:
* implementation.
*/
virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const = 0;
-
-protected:
- /**
- * The destructor will never be called. See cleanShutdown instead.
- */
- virtual ~StorageEngine() {}
};
} // namespace mongo
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp
index e40d3a58edb..dfc59b26f3f 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp
@@ -39,7 +39,7 @@
namespace mongo {
/* Make a WiredTigerCustomizationHooks pointer a decoration on the global ServiceContext */
-MONGO_INITIALIZER_WITH_PREREQUISITES(SetWiredTigerCustomizationHooks, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(SetWiredTigerCustomizationHooks)
(InitializerContext* context) {
auto customizationHooks = stdx::make_unique<WiredTigerCustomizationHooks>();
WiredTigerCustomizationHooks::set(getGlobalServiceContext(), std::move(customizationHooks));
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp
index f9bd90126e2..b0149c0b5aa 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp
@@ -38,7 +38,7 @@
namespace mongo {
-MONGO_INITIALIZER_WITH_PREREQUISITES(SetWiredTigerExtensions, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(SetWiredTigerExtensions)
(InitializerContext* context) {
auto configHooks = stdx::make_unique<WiredTigerExtensions>();
WiredTigerExtensions::set(getGlobalServiceContext(), std::move(configHooks));
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
index 1e839e2c1ac..5b7d2cc2239 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
@@ -166,7 +166,7 @@ public:
};
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(WiredTigerEngineInit, ("SetGlobalEnvironment"))
+MONGO_INITIALIZER(WiredTigerEngineInit)
(InitializerContext* context) {
getGlobalServiceContext()->registerStorageEngine(kWiredTigerEngineName,
new WiredTigerFactory());
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp
index 770b1d9b3cd..118471655ad 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp
@@ -35,8 +35,10 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_registrar.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h"
-#include "mongo/stdx/memory.h"
+
+#include <memory>
namespace mongo {
namespace {
@@ -50,9 +52,8 @@ MONGO_INITIALIZER(SetInitRsOplogBackgroundThreadCallback)(InitializerContext* co
return Status::OK();
}
-MONGO_INITIALIZER(SetGlobalEnvironment)(InitializerContext* context) {
- setGlobalServiceContext(stdx::make_unique<ServiceContextNoop>());
- return Status::OK();
-}
+ServiceContextRegistrar serviceContextCreator([]() {
+ return std::make_unique<ServiceContextNoop>();
+});
} // namespace
} // namespace mongo