summaryrefslogtreecommitdiff
path: root/src/mongo/db/cursor_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/cursor_manager.cpp')
-rw-r--r--src/mongo/db/cursor_manager.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp
index 7f2b9fbe199..4ae9bafd9ed 100644
--- a/src/mongo/db/cursor_manager.cpp
+++ b/src/mongo/db/cursor_manager.cpp
@@ -637,14 +637,19 @@ void CursorManager::unpin(OperationContext* opCtx, ClientCursor* cursor) {
auto interruptStatus = cursor->_operationUsingCursor->checkForInterruptNoAssert();
cursor->_operationUsingCursor = nullptr;
cursor->_lastUseDate = now;
- if (!interruptStatus.isOK()) {
- // If an interrupt occurred after the batch was completed, we remove the now-unpinned cursor
- // from the CursorManager, then dispose of and delete it.
+
+ // If someone was trying to kill this cursor with a killOp or a killCursors, they are likely
+ // interesting in proactively cleaning up that cursor's resources. In these cases, we
+ // proactively delete the cursor. In other cases we preserve the error code so that the client
+ // will see the reason the cursor was killed when asking for the next batch.
+ if (interruptStatus == ErrorCodes::Interrupted || interruptStatus == ErrorCodes::CursorKilled) {
LOG(0) << "removing cursor " << cursor->cursorid()
<< " after completing batch: " << interruptStatus;
partition->erase(cursor->cursorid());
cursor->dispose(opCtx);
delete cursor;
+ } else if (!interruptStatus.isOK()) {
+ cursor->markAsKilled(interruptStatus);
}
}