void ClusterCursorManager::PinnedCursor::returnAndKillCursor() { invariant(_cursor); // Inform the manager that the cursor should be killed. invariantOK(_manager->killCursor(_nss, _cursorId)); // Return the cursor to the manager. It will be deleted on the next call to // ClusterCursorManager::reapZombieCursors(). // // The value of the argument to returnCursor() doesn't matter; the cursor will be kept as a // zombie. returnCursor(CursorState::NotExhausted); }
StatusWith<BSONObj> storePossibleCursor(const HostAndPort& server, const BSONObj& cmdResult, executor::TaskExecutor* executor, ClusterCursorManager* cursorManager) { if (!useClusterClientCursor) { Status status = storePossibleCursorLegacy(server, cmdResult); return (status.isOK() ? StatusWith<BSONObj>(cmdResult) : StatusWith<BSONObj>(status)); } if (!cmdResult["ok"].trueValue() || !cmdResult.hasField("cursor")) { return cmdResult; } auto incomingCursorResponse = CursorResponse::parseFromBSON(cmdResult); if (!incomingCursorResponse.isOK()) { return incomingCursorResponse.getStatus(); } if (incomingCursorResponse.getValue().getCursorId() == CursorId(0)) { return cmdResult; } ClusterClientCursorParams params(incomingCursorResponse.getValue().getNSS()); params.remotes.emplace_back(server, incomingCursorResponse.getValue().getCursorId()); auto ccc = stdx::make_unique<ClusterClientCursorImpl>(executor, std::move(params)); auto pinnedCursor = cursorManager->registerCursor(std::move(ccc), incomingCursorResponse.getValue().getNSS(), ClusterCursorManager::CursorType::NamespaceNotSharded, ClusterCursorManager::CursorLifetime::Mortal); CursorId clusterCursorId = pinnedCursor.getCursorId(); pinnedCursor.returnCursor(ClusterCursorManager::CursorState::NotExhausted); CursorResponse outgoingCursorResponse(incomingCursorResponse.getValue().getNSS(), clusterCursorId, incomingCursorResponse.getValue().getBatch()); return outgoingCursorResponse.toBSON(CursorResponse::ResponseType::InitialResponse); }