summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency/lock_state.cpp
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2019-04-16 08:54:33 -0400
committerDaniel Gottlieb <daniel.gottlieb@mongodb.com>2019-04-16 09:08:31 -0400
commit2b921ed8695e9ce2a4ce1036ac524450f5a48d8a (patch)
treee6e37273f8d738bd619cc77bd34bccd71027212e /src/mongo/db/concurrency/lock_state.cpp
parent0a5f343a8440f575856e4eff51b4e1cc0d01a0db (diff)
downloadmongo-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.cpp13
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);
}
}