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/query/internal_plans.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/query/internal_plans.cpp')
-rw-r--r-- | src/mongo/db/query/internal_plans.cpp | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/src/mongo/db/query/internal_plans.cpp b/src/mongo/db/query/internal_plans.cpp index b09e550b863..6b1ae0857b7 100644 --- a/src/mongo/db/query/internal_plans.cpp +++ b/src/mongo/db/query/internal_plans.cpp @@ -43,12 +43,13 @@ namespace mongo { -std::unique_ptr<PlanExecutor> InternalPlanner::collectionScan(OperationContext* opCtx, - StringData ns, - Collection* collection, - PlanExecutor::YieldPolicy yieldPolicy, - const Direction direction, - const RecordId startLoc) { +std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::collectionScan( + OperationContext* opCtx, + StringData ns, + Collection* collection, + PlanExecutor::YieldPolicy yieldPolicy, + const Direction direction, + const RecordId startLoc) { std::unique_ptr<WorkingSet> ws = stdx::make_unique<WorkingSet>(); if (NULL == collection) { @@ -71,7 +72,7 @@ std::unique_ptr<PlanExecutor> InternalPlanner::collectionScan(OperationContext* return std::move(statusWithPlanExecutor.getValue()); } -std::unique_ptr<PlanExecutor> InternalPlanner::deleteWithCollectionScan( +std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWithCollectionScan( OperationContext* opCtx, Collection* collection, const DeleteStageParams& params, @@ -91,15 +92,16 @@ std::unique_ptr<PlanExecutor> InternalPlanner::deleteWithCollectionScan( } -std::unique_ptr<PlanExecutor> InternalPlanner::indexScan(OperationContext* opCtx, - const Collection* collection, - const IndexDescriptor* descriptor, - const BSONObj& startKey, - const BSONObj& endKey, - BoundInclusion boundInclusion, - PlanExecutor::YieldPolicy yieldPolicy, - Direction direction, - int options) { +std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::indexScan( + OperationContext* opCtx, + const Collection* collection, + const IndexDescriptor* descriptor, + const BSONObj& startKey, + const BSONObj& endKey, + BoundInclusion boundInclusion, + PlanExecutor::YieldPolicy yieldPolicy, + Direction direction, + int options) { auto ws = stdx::make_unique<WorkingSet>(); std::unique_ptr<PlanStage> root = _indexScan(opCtx, @@ -118,7 +120,7 @@ std::unique_ptr<PlanExecutor> InternalPlanner::indexScan(OperationContext* opCtx return std::move(executor.getValue()); } -std::unique_ptr<PlanExecutor> InternalPlanner::deleteWithIndexScan( +std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWithIndexScan( OperationContext* opCtx, Collection* collection, const DeleteStageParams& params, @@ -148,7 +150,7 @@ std::unique_ptr<PlanExecutor> InternalPlanner::deleteWithIndexScan( return std::move(executor.getValue()); } -std::unique_ptr<PlanExecutor> InternalPlanner::updateWithIdHack( +std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::updateWithIdHack( OperationContext* opCtx, Collection* collection, const UpdateStageParams& params, |