summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/client.cpp8
-rw-r--r--src/mongo/db/client.h16
-rw-r--r--src/mongo/db/operation_context.cpp15
3 files changed, 35 insertions, 4 deletions
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index ec0283e0468..77204405f3c 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -183,6 +183,14 @@ bool Client::hasAnyActiveCurrentOp() const {
return false;
}
+void Client::setKilled() noexcept {
+ stdx::lock_guard<Client> lk(*this);
+ _killed.store(true);
+ if (_opCtx) {
+ _serviceContext->killOperation(lk, _opCtx, ErrorCodes::ClientMarkedKilled);
+ }
+}
+
ThreadClient::ThreadClient(ServiceContext* serviceContext)
: ThreadClient(getThreadName(), serviceContext, nullptr) {}
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index f98d17d5252..3ffed27adc2 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -41,6 +41,7 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/service_context.h"
+#include "mongo/platform/atomic_word.h"
#include "mongo/platform/random.h"
#include "mongo/stdx/thread.h"
#include "mongo/transport/session.h"
@@ -246,6 +247,19 @@ public:
*/
bool hasAnyActiveCurrentOp() const;
+ /**
+ * Signal the client's OperationContext that it has been killed.
+ * Any future OperationContext on this client will also receive a kill signal.
+ */
+ void setKilled() noexcept;
+
+ /**
+ * Get the state for killing the client's OperationContext.
+ */
+ bool getKilled() const noexcept {
+ return _killed.loadRelaxed();
+ }
+
private:
friend class ServiceContext;
friend class ThreadClient;
@@ -275,6 +289,8 @@ private:
bool _systemOperationKillable = false;
PseudoRandom _prng;
+
+ AtomicWord<bool> _killed{false};
};
/**
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp
index ee38faab01b..a0bee37b49b 100644
--- a/src/mongo/db/operation_context.cpp
+++ b/src/mongo/db/operation_context.cpp
@@ -203,10 +203,17 @@ bool opShouldFail(Client* client, const BSONObj& failPointInfo) {
} // namespace
Status OperationContext::checkForInterruptNoAssert() noexcept {
- // TODO: Remove the MONGO_likely(getClient()) once all operation contexts are constructed with
- // clients.
- if (MONGO_likely(getClient() && getServiceContext()) &&
- getServiceContext()->getKillAllOperations() && !_isExecutingShutdown) {
+ // TODO: Remove the MONGO_likely(hasClientAndServiceContext) once all operation contexts are
+ // constructed with clients.
+ const auto hasClientAndServiceContext = getClient() && getServiceContext();
+
+ if (MONGO_likely(hasClientAndServiceContext) && getClient()->getKilled() &&
+ !_isExecutingShutdown) {
+ return Status(ErrorCodes::ClientMarkedKilled, "client has been killed");
+ }
+
+ if (MONGO_likely(hasClientAndServiceContext) && getServiceContext()->getKillAllOperations() &&
+ !_isExecutingShutdown) {
return Status(ErrorCodes::InterruptedAtShutdown, "interrupted at shutdown");
}