diff options
author | Dianna Hohensee <dianna.hohensee@mongodb.com> | 2020-10-22 16:54:59 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-02 19:55:18 +0000 |
commit | f5337c32ab8470454af46a3e391575840a5b39ce (patch) | |
tree | a21b194c45c4fbaa48c0afcbda533d27edbd19ea /src/mongo/db/operation_context.h | |
parent | 0008250ba85ce47e054241eedec8cddcda1c96d6 (diff) | |
download | mongo-f5337c32ab8470454af46a3e391575840a5b39ce.tar.gz |
SERVER-51396 Add a LockFreeReadsBlock that sets a flag on the OperationContext in order to safely bypass RSTL lock invariants for lock-free reads.
Diffstat (limited to 'src/mongo/db/operation_context.h')
-rw-r--r-- | src/mongo/db/operation_context.h | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h index 7997674747d..dbb21caf7d3 100644 --- a/src/mongo/db/operation_context.h +++ b/src/mongo/db/operation_context.h @@ -283,6 +283,13 @@ public: } /** + * Returns true if the operation is running lock-free. + */ + bool isLockFreeReadsOp() const { + return _isLockFreeReadsOp; + } + + /** * Returns true if operations' durations should be added to serverStatus latency metrics. */ bool shouldIncrementLatencyStats() const { @@ -572,8 +579,16 @@ private: _writesAreReplicated = writesAreReplicated; } + /** + * Set whether or not the operation is running lock-free. + */ + void setIsLockFreeReadsOp(bool isLockFreeReadsOp) { + _isLockFreeReadsOp = isLockFreeReadsOp; + } + friend class WriteUnitOfWork; friend class repl::UnreplicatedWritesBlock; + friend class LockFreeReadsBlock; Client* const _client; @@ -626,6 +641,7 @@ private: Timer _elapsedTime; bool _writesAreReplicated = true; + bool _isLockFreeReadsOp = false; bool _shouldIncrementLatencyStats = true; bool _shouldParticipateInFlowControl = true; bool _inMultiDocumentTransaction = false; @@ -673,4 +689,29 @@ private: const bool _shouldReplicateWrites; }; } // namespace repl + +/** + * RAII-style class to indicate the operation is lock-free and code should behave accordingly. + */ +class LockFreeReadsBlock { + LockFreeReadsBlock(const LockFreeReadsBlock&) = delete; + LockFreeReadsBlock& operator=(const LockFreeReadsBlock&) = delete; + +public: + LockFreeReadsBlock(OperationContext* opCtx) + : _opCtx(opCtx), _previousLockFreeReadsSetting(opCtx->isLockFreeReadsOp()) { + opCtx->setIsLockFreeReadsOp(true); + } + + ~LockFreeReadsBlock() { + _opCtx->setIsLockFreeReadsOp(_previousLockFreeReadsSetting); + } + +private: + OperationContext* _opCtx; + + // Used to re-set the value on the operation context upon destruction that was originally set. + const bool _previousLockFreeReadsSetting; +}; + } // namespace mongo |