summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/service_context.cpp66
-rw-r--r--src/mongo/db/service_context.h29
-rw-r--r--src/mongo/db/service_context_d.cpp74
-rw-r--r--src/mongo/db/service_context_d.h26
-rw-r--r--src/mongo/db/service_context_noop.cpp17
-rw-r--r--src/mongo/db/service_context_noop.h12
6 files changed, 92 insertions, 132 deletions
diff --git a/src/mongo/db/service_context.cpp b/src/mongo/db/service_context.cpp
index 6f42a4a547b..894d08c3fd9 100644
--- a/src/mongo/db/service_context.cpp
+++ b/src/mongo/db/service_context.cpp
@@ -276,4 +276,70 @@ BSONArray storageEngineList() {
void appendStorageEngineList(BSONObjBuilder* result) {
result->append("storageEngines", storageEngineList());
}
+
+void ServiceContext::setKillAllOperations() {
+ stdx::lock_guard<stdx::mutex> clientLock(_mutex);
+ _globalKill.store(true);
+ for (const auto listener : _killOpListeners) {
+ try {
+ listener->interruptAll();
+ } catch (...) {
+ std::terminate();
+ }
+ }
+}
+
+void ServiceContext::_killOperation_inlock(OperationContext* opCtx, ErrorCodes::Error killCode) {
+ opCtx->markKilled(killCode);
+
+ for (const auto listener : _killOpListeners) {
+ try {
+ listener->interrupt(opCtx->getOpID());
+ } catch (...) {
+ std::terminate();
+ }
+ }
+}
+
+bool ServiceContext::killOperation(unsigned int opId) {
+ for (LockedClientsCursor cursor(this); Client* client = cursor.next();) {
+ stdx::lock_guard<Client> lk(*client);
+
+ OperationContext* opCtx = client->getOperationContext();
+ if (opCtx && opCtx->getOpID() == opId) {
+ _killOperation_inlock(opCtx, ErrorCodes::Interrupted);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ServiceContext::killAllUserOperations(const OperationContext* txn,
+ ErrorCodes::Error killCode) {
+ for (LockedClientsCursor cursor(this); Client* client = cursor.next();) {
+ if (!client->isFromUserConnection()) {
+ // Don't kill system operations.
+ continue;
+ }
+
+ stdx::lock_guard<Client> lk(*client);
+ OperationContext* toKill = client->getOperationContext();
+
+ // Don't kill ourself.
+ if (toKill && toKill->getOpID() != txn->getOpID()) {
+ _killOperation_inlock(toKill, killCode);
+ }
+ }
+}
+
+void ServiceContext::unsetKillAllOperations() {
+ _globalKill.store(false);
+}
+
+void ServiceContext::registerKillOpListener(KillOpListenerInterface* listener) {
+ stdx::lock_guard<stdx::mutex> clientLock(_mutex);
+ _killOpListeners.push_back(listener);
+}
+
} // namespace mongo
diff --git a/src/mongo/db/service_context.h b/src/mongo/db/service_context.h
index 1cba9bdb05d..a27a799efd2 100644
--- a/src/mongo/db/service_context.h
+++ b/src/mongo/db/service_context.h
@@ -33,6 +33,7 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/db/storage/storage_engine.h"
+#include "mongo/platform/atomic_word.h"
#include "mongo/platform/unordered_set.h"
#include "mongo/stdx/functional.h"
#include "mongo/stdx/mutex.h"
@@ -262,30 +263,32 @@ public:
/**
* Signal all OperationContext(s) that they have been killed.
*/
- virtual void setKillAllOperations() = 0;
+ void setKillAllOperations();
/**
* Reset the operation kill state after a killAllOperations.
* Used for testing.
*/
- virtual void unsetKillAllOperations() = 0;
+ void unsetKillAllOperations();
/**
* Get the state for killing all operations.
*/
- virtual bool getKillAllOperations() = 0;
+ bool getKillAllOperations() {
+ return _globalKill.loadRelaxed();
+ }
/**
* @param i opid of operation to kill
* @return if operation was found
**/
- virtual bool killOperation(unsigned int opId) = 0;
+ bool killOperation(unsigned int opId);
/**
* Kills all operations that have a Client that is associated with an incoming user
* connection, except for the one associated with txn.
*/
- virtual void killAllUserOperations(const OperationContext* txn, ErrorCodes::Error killCode) = 0;
+ void killAllUserOperations(const OperationContext* txn, ErrorCodes::Error killCode);
/**
* Registers a listener to be notified each time an op is killed.
@@ -293,7 +296,7 @@ public:
* listener does not become owned by the environment. As there is currently no way to
* unregister, the listener object must outlive this ServiceContext object.
*/
- virtual void registerKillOpListener(KillOpListenerInterface* listener) = 0;
+ void registerKillOpListener(KillOpListenerInterface* listener);
//
// Global OpObserver.
@@ -359,6 +362,14 @@ private:
virtual std::unique_ptr<OperationContext> _newOpCtx(Client* client) = 0;
/**
+ * Kills the given operation.
+ *
+ * Caller must own the service context's _mutex.
+ */
+ void _killOperation_inlock(OperationContext* opCtx, ErrorCodes::Error killCode);
+
+
+ /**
* Vector of registered observers.
*/
std::vector<std::unique_ptr<ClientObserver>> _clientObservers;
@@ -376,6 +387,12 @@ private:
* A ClockSource implementation that is very precise but may be expensive to call.
*/
std::unique_ptr<ClockSource> _preciseClockSource;
+
+ // Flag set to indicate that all operations are to be interrupted ASAP.
+ AtomicWord<bool> _globalKill{false};
+
+ // protected by _mutex
+ std::vector<KillOpListenerInterface*> _killOpListeners;
};
/**
diff --git a/src/mongo/db/service_context_d.cpp b/src/mongo/db/service_context_d.cpp
index b82f89c4c05..aac7296a5a4 100644
--- a/src/mongo/db/service_context_d.cpp
+++ b/src/mongo/db/service_context_d.cpp
@@ -66,9 +66,9 @@ MONGO_INITIALIZER(SetGlobalEnvironment)(InitializerContext* context) {
return Status::OK();
}
-ServiceContextMongoD::ServiceContextMongoD() : _globalKill(false), _storageEngine(NULL) {}
+ServiceContextMongoD::ServiceContextMongoD() = default;
-ServiceContextMongoD::~ServiceContextMongoD() {}
+ServiceContextMongoD::~ServiceContextMongoD() = default;
StorageEngine* ServiceContextMongoD::getGlobalStorageEngine() {
// We don't check that globalStorageEngine is not-NULL here intentionally. We can encounter
@@ -252,76 +252,6 @@ const StorageEngine::Factory* StorageFactoriesIteratorMongoD::next() {
return _curr++->second;
}
-void ServiceContextMongoD::setKillAllOperations() {
- stdx::lock_guard<stdx::mutex> clientLock(_mutex);
- _globalKill = true;
- for (const auto listener : _killOpListeners) {
- try {
- listener->interruptAll();
- } catch (...) {
- std::terminate();
- }
- }
-}
-
-bool ServiceContextMongoD::getKillAllOperations() {
- return _globalKill;
-}
-
-void ServiceContextMongoD::_killOperation_inlock(OperationContext* opCtx,
- ErrorCodes::Error killCode) {
- opCtx->markKilled(killCode);
-
- for (const auto listener : _killOpListeners) {
- try {
- listener->interrupt(opCtx->getOpID());
- } catch (...) {
- std::terminate();
- }
- }
-}
-
-bool ServiceContextMongoD::killOperation(unsigned int opId) {
- for (LockedClientsCursor cursor(this); Client* client = cursor.next();) {
- stdx::lock_guard<Client> lk(*client);
-
- OperationContext* opCtx = client->getOperationContext();
- if (opCtx && opCtx->getOpID() == opId) {
- _killOperation_inlock(opCtx, ErrorCodes::Interrupted);
- return true;
- }
- }
-
- return false;
-}
-
-void ServiceContextMongoD::killAllUserOperations(const OperationContext* txn,
- ErrorCodes::Error killCode) {
- for (LockedClientsCursor cursor(this); Client* client = cursor.next();) {
- if (!client->isFromUserConnection()) {
- // Don't kill system operations.
- continue;
- }
-
- stdx::lock_guard<Client> lk(*client);
- OperationContext* toKill = client->getOperationContext();
-
- // Don't kill ourself.
- if (toKill && toKill->getOpID() != txn->getOpID()) {
- _killOperation_inlock(toKill, killCode);
- }
- }
-}
-
-void ServiceContextMongoD::unsetKillAllOperations() {
- _globalKill = false;
-}
-
-void ServiceContextMongoD::registerKillOpListener(KillOpListenerInterface* listener) {
- stdx::lock_guard<stdx::mutex> clientLock(_mutex);
- _killOpListeners.push_back(listener);
-}
-
std::unique_ptr<OperationContext> ServiceContextMongoD::_newOpCtx(Client* client) {
invariant(&cc() == client);
return std::unique_ptr<OperationContextImpl>(new OperationContextImpl());
diff --git a/src/mongo/db/service_context_d.h b/src/mongo/db/service_context_d.h
index ce806a80240..a773fab2b61 100644
--- a/src/mongo/db/service_context_d.h
+++ b/src/mongo/db/service_context_d.h
@@ -61,18 +61,6 @@ public:
StorageFactoriesIterator* makeStorageFactoriesIterator() override;
- void setKillAllOperations() override;
-
- void unsetKillAllOperations() override;
-
- bool getKillAllOperations() override;
-
- bool killOperation(unsigned int opId) override;
-
- void killAllUserOperations(const OperationContext* txn, ErrorCodes::Error killCode) override;
-
- void registerKillOpListener(KillOpListenerInterface* listener) override;
-
void setOpObserver(std::unique_ptr<OpObserver> opObserver) override;
OpObserver* getOpObserver() override;
@@ -80,22 +68,10 @@ public:
private:
std::unique_ptr<OperationContext> _newOpCtx(Client* client) override;
- /**
- * Kills the given operation.
- *
- * Caller must own the service context's _mutex.
- */
- void _killOperation_inlock(OperationContext* opCtx, ErrorCodes::Error killCode);
-
- bool _globalKill;
-
- // protected by parent class's _mutex
- std::vector<KillOpListenerInterface*> _killOpListeners;
-
std::unique_ptr<StorageEngineLockFile> _lockFile;
// logically owned here, but never deleted by anyone.
- StorageEngine* _storageEngine;
+ StorageEngine* _storageEngine = nullptr;
// logically owned here.
std::unique_ptr<OpObserver> _opObserver;
diff --git a/src/mongo/db/service_context_noop.cpp b/src/mongo/db/service_context_noop.cpp
index fd94b35db89..0280d1b4742 100644
--- a/src/mongo/db/service_context_noop.cpp
+++ b/src/mongo/db/service_context_noop.cpp
@@ -67,23 +67,6 @@ StorageFactoriesIterator* ServiceContextNoop::makeStorageFactoriesIterator() {
return new EmptySFI();
}
-void ServiceContextNoop::setKillAllOperations() {}
-
-void ServiceContextNoop::unsetKillAllOperations() {}
-
-bool ServiceContextNoop::getKillAllOperations() {
- return false;
-}
-
-bool ServiceContextNoop::killOperation(unsigned int opId) {
- return false;
-}
-
-void ServiceContextNoop::killAllUserOperations(const OperationContext* txn,
- ErrorCodes::Error killCode) {}
-
-void ServiceContextNoop::registerKillOpListener(KillOpListenerInterface* listener) {}
-
std::unique_ptr<OperationContext> ServiceContextNoop::_newOpCtx(Client* client) {
return stdx::make_unique<OperationContextNoop>(client, _nextOpId.fetchAndAdd(1));
}
diff --git a/src/mongo/db/service_context_noop.h b/src/mongo/db/service_context_noop.h
index 7fce23a6a4a..8e80509df10 100644
--- a/src/mongo/db/service_context_noop.h
+++ b/src/mongo/db/service_context_noop.h
@@ -49,18 +49,6 @@ public:
StorageFactoriesIterator* makeStorageFactoriesIterator() override;
- bool killOperation(unsigned int opId) override;
-
- void killAllUserOperations(const OperationContext* txn, ErrorCodes::Error killCode) override;
-
- void setKillAllOperations() override;
-
- void unsetKillAllOperations() override;
-
- bool getKillAllOperations() override;
-
- void registerKillOpListener(KillOpListenerInterface* listener) override;
-
void setOpObserver(std::unique_ptr<OpObserver> opObserver) override;
OpObserver* getOpObserver() override;