diff options
author | Blake Oler <blake.oler@mongodb.com> | 2022-09-07 12:55:26 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-09-07 13:55:20 +0000 |
commit | 16b22af0483333fba942c835cdc4ab5ae3dfcf23 (patch) | |
tree | 3242b152cab61afd564c6f1c0ef809eb06a29c19 /src/mongo | |
parent | 0eb043641e902e48f319f1b89a6739a46bb80147 (diff) | |
download | mongo-16b22af0483333fba942c835cdc4ab5ae3dfcf23.tar.gz |
SERVER-68240 Fix iterator race condition in WaitForMajorityService
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/repl/wait_for_majority_service.cpp | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/mongo/db/repl/wait_for_majority_service.cpp b/src/mongo/db/repl/wait_for_majority_service.cpp index 5d448cdd3d3..06ece2155f3 100644 --- a/src/mongo/db/repl/wait_for_majority_service.cpp +++ b/src/mongo/db/repl/wait_for_majority_service.cpp @@ -161,7 +161,7 @@ SemiFuture<void> WaitForMajorityService::waitUntilMajority(const repl::OpTime& o scopedClientLock, opCtx, ErrorCodes::WaitForMajorityServiceEarlierOpTimeAvailable); } - auto resultIter = _queuedOpTimes.emplace( + _queuedOpTimes.emplace( std::piecewise_construct, std::forward_as_tuple(opTime), std::forward_as_tuple(request)); @@ -170,7 +170,7 @@ SemiFuture<void> WaitForMajorityService::waitUntilMajority(const repl::OpTime& o _hasNewOpTimeCV.notifyAllAndReset(); } - cancelToken.onCancel().thenRunOn(_pool).getAsync([this, resultIter, request](Status s) { + cancelToken.onCancel().thenRunOn(_pool).getAsync([this, request](Status s) { if (!s.isOK()) { return; } @@ -178,7 +178,12 @@ SemiFuture<void> WaitForMajorityService::waitUntilMajority(const repl::OpTime& o if (!request->hasBeenProcessed.swap(true)) { request->result.setError(waitUntilMajorityCanceledStatus()); stdx::lock_guard lk(_mutex); - _queuedOpTimes.erase(resultIter); + auto it = std::find_if( + std::begin(_queuedOpTimes), + std::end(_queuedOpTimes), + [&request](auto&& requestIter) { return request == requestIter.second; }); + invariant(it != _queuedOpTimes.end()); + _queuedOpTimes.erase(it); } }); return std::move(future).semi(); |