summaryrefslogtreecommitdiff
path: root/src/mongo/db/client_out_of_line_executor.cpp
diff options
context:
space:
mode:
authorAmirsaman Memaripour <amirsaman.memaripour@mongodb.com>2020-06-25 15:45:24 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-06-25 23:12:58 +0000
commit341fb5d34695cb7d0994f5d91947355d60dabf36 (patch)
treeaf5432f0e423d91bd6eee4e11393de57bdf6b15f /src/mongo/db/client_out_of_line_executor.cpp
parent2fbc2ed9269db23c17eeed2acc6b94dceee025bb (diff)
downloadmongo-341fb5d34695cb7d0994f5d91947355d60dabf36.tar.gz
SERVER-48901 Have a client observer destroy ClientOutOfLineExecutor
Diffstat (limited to 'src/mongo/db/client_out_of_line_executor.cpp')
-rw-r--r--src/mongo/db/client_out_of_line_executor.cpp31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/mongo/db/client_out_of_line_executor.cpp b/src/mongo/db/client_out_of_line_executor.cpp
index 5aa83a66d18..e2fe618165f 100644
--- a/src/mongo/db/client_out_of_line_executor.cpp
+++ b/src/mongo/db/client_out_of_line_executor.cpp
@@ -33,6 +33,7 @@
#include "mongo/base/error_codes.h"
#include "mongo/base/status.h"
+#include "mongo/db/service_context.h"
#include "mongo/logv2/log.h"
#include "mongo/logv2/log_severity.h"
#include "mongo/logv2/log_severity_suppressor.h"
@@ -54,6 +55,12 @@ ClientOutOfLineExecutor::ClientOutOfLineExecutor() noexcept
: _impl{std::make_unique<Impl>()}, _taskQueue{std::make_shared<QueueType>()} {}
ClientOutOfLineExecutor::~ClientOutOfLineExecutor() noexcept {
+ invariant(_isShutdown);
+}
+
+void ClientOutOfLineExecutor::shutdown() {
+ ON_BLOCK_EXIT([this]() mutable { _isShutdown = true; });
+
// Force producers to consume their tasks beyond this point.
_taskQueue->closeProducerEnd();
@@ -117,4 +124,28 @@ void ClientOutOfLineExecutor::QueueHandle::schedule(Task&& task) {
}
}
+namespace {
+
+/**
+ * The observer ensures that `ClientOutOfLineExecutor` is always stopped before the client object is
+ * destroyed. This is necessary to guarantee that `ClientOutOfLineExecutor::shutdown()` is executed
+ * before the client decorations are destroyed. See SERVER-48901 for more details.
+ */
+class ClientOutOfLineExecutorClientObserver final : public ServiceContext::ClientObserver {
+ void onCreateClient(Client*) {}
+ void onDestroyClient(Client* client) {
+ ClientOutOfLineExecutor::get(client)->shutdown();
+ }
+ void onCreateOperationContext(OperationContext*) {}
+ void onDestroyOperationContext(OperationContext*) {}
+};
+
+ServiceContext::ConstructorActionRegisterer
+ registerClientOutOfLineExecutorClientObserverConstructor{
+ "ClientOutOfLineExecutorClientObserverConstructor", [](ServiceContext* service) {
+ service->registerClientObserver(
+ std::make_unique<ClientOutOfLineExecutorClientObserver>());
+ }};
+
+} // namespace
} // namespace mongo