diff options
author | Charlie Swanson <charlie.swanson@mongodb.com> | 2017-04-05 11:35:23 -0400 |
---|---|---|
committer | Charlie Swanson <charlie.swanson@mongodb.com> | 2017-04-13 16:15:20 -0400 |
commit | cc954e9e1d88b30d1ab89ee3bbbd9db0bb15263d (patch) | |
tree | 37df000f0d37d17bc82d5d1ad5436b4911249e4b /src/mongo/db/repl/storage_interface_impl.cpp | |
parent | b02b7f7bb78d4fd0bb006591769faaa216e6f8a7 (diff) | |
download | mongo-cc954e9e1d88b30d1ab89ee3bbbd9db0bb15263d.tar.gz |
SERVER-25694 Eliminate race in PlanExecutor cleanup.
Ensures that a collection lock is held in at least MODE_IS while
deregistering a PlanExecutor from the cursor manager. Introduces new
PlanExecutor::dispose() and ClientCursor::dispose() methods that must be
called before destruction of those classes, and ensures they are called
before destruction. These calls will thread an OperationContext all the
way through to DocumentSource::dispose() for each stage in a Pipeline,
which will give DocumentSourceCursor a chance to acquire locks and
deregister its PlanExecutor if necessary.
Diffstat (limited to 'src/mongo/db/repl/storage_interface_impl.cpp')
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.cpp | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index 858c49027ae..5700f0a4fcd 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -495,7 +495,7 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments( auto isForward = scanDirection == StorageInterface::ScanDirection::kForward; auto direction = isForward ? InternalPlanner::FORWARD : InternalPlanner::BACKWARD; - std::unique_ptr<PlanExecutor> planExecutor; + std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> planExecutor; if (!indexName) { if (!startKey.isEmpty()) { return {ErrorCodes::NoSuchKey, @@ -509,12 +509,12 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments( // Use collection scan. planExecutor = isFind ? InternalPlanner::collectionScan( - opCtx, nss.ns(), collection, PlanExecutor::YIELD_MANUAL, direction) + opCtx, nss.ns(), collection, PlanExecutor::NO_YIELD, direction) : InternalPlanner::deleteWithCollectionScan( opCtx, collection, makeDeleteStageParamsForDeleteDocuments(), - PlanExecutor::YIELD_MANUAL, + PlanExecutor::NO_YIELD, direction); } else { // Use index scan. @@ -551,7 +551,7 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments( bounds.first, bounds.second, boundInclusion, - PlanExecutor::YIELD_MANUAL, + PlanExecutor::NO_YIELD, direction, InternalPlanner::IXSCAN_FETCH) : InternalPlanner::deleteWithIndexScan(opCtx, @@ -561,7 +561,7 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments( bounds.first, bounds.second, boundInclusion, - PlanExecutor::YIELD_MANUAL, + PlanExecutor::NO_YIELD, direction); } @@ -659,7 +659,7 @@ Status StorageInterfaceImpl::upsertById(OperationContext* opCtx, request.setUpsert(true); invariant(!request.isMulti()); // This follows from using an exact _id query. invariant(!request.shouldReturnAnyDocs()); - invariant(PlanExecutor::YIELD_MANUAL == request.getYieldPolicy()); + invariant(PlanExecutor::NO_YIELD == request.getYieldPolicy()); MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN { // ParsedUpdate needs to be inside the write conflict retry loop because it contains |