diff options
author | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2019-04-16 08:54:33 -0400 |
---|---|---|
committer | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2019-04-16 09:08:31 -0400 |
commit | 2b921ed8695e9ce2a4ce1036ac524450f5a48d8a (patch) | |
tree | e6e37273f8d738bd619cc77bd34bccd71027212e /src/mongo/db/concurrency/lock_state.cpp | |
parent | 0a5f343a8440f575856e4eff51b4e1cc0d01a0db (diff) | |
download | mongo-2b921ed8695e9ce2a4ce1036ac524450f5a48d8a.tar.gz |
SERVER-40615: Only get flow-control tickets when the client was previously inactive.
Diffstat (limited to 'src/mongo/db/concurrency/lock_state.cpp')
-rw-r--r-- | src/mongo/db/concurrency/lock_state.cpp | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp index 77fdd470462..e5b095fdb66 100644 --- a/src/mongo/db/concurrency/lock_state.cpp +++ b/src/mongo/db/concurrency/lock_state.cpp @@ -710,6 +710,7 @@ void LockerImpl::restoreLockState(OperationContext* opCtx, const Locker::LockSna // We shouldn't be saving and restoring lock state from inside a WriteUnitOfWork. invariant(!inAWriteUnitOfWork()); invariant(_modeForTicket == MODE_NONE); + invariant(_clientState.load() == kInactive); if (opCtx) { getFlowControlTicket(opCtx, state.globalMode); @@ -898,14 +899,14 @@ void LockerImpl::lockComplete(OperationContext* opCtx, void LockerImpl::getFlowControlTicket(OperationContext* opCtx, LockMode lockMode) { auto ticketholder = FlowControlTicketholder::get(opCtx); - if (ticketholder && lockMode == LockMode::MODE_IX) { - // FlowControl only acts when a MODE_IX global lock is being taken. The clientState - // necessarily should only swap to being a queued writer followed by becoming an active - // writer. This will report clients waiting on flow control inside serverStatus' - // `currentQueue` metrics. + if (ticketholder && lockMode == LockMode::MODE_IX && _clientState.load() == kInactive) { + // FlowControl only acts when a MODE_IX global lock is being taken. The clientState is only + // being modified here to change serverStatus' `globalLock.currentQueue` metrics. This + // method must not exit with a side-effect on the clientState. That value is also used for + // tracking whether other resources need to be released. _clientState.store(kQueuedWriter); + auto restoreState = makeGuard([&] { _clientState.store(kInactive); }); ticketholder->getTicket(opCtx, &_flowControlStats); - _clientState.store(kActiveWriter); } } |