Пример #1
0
void ClusterCursorManager::checkInCursor(std::unique_ptr<ClusterClientCursor> cursor,
                                         const NamespaceString& nss,
                                         CursorId cursorId,
                                         CursorState cursorState) {
    stdx::unique_lock<stdx::mutex> lk(_mutex);

    invariant(cursor);

    const bool remotesExhausted = cursor->remotesExhausted();

    CursorEntry* entry = getEntry_inlock(nss, cursorId);
    invariant(entry);

    entry->returnCursor(std::move(cursor));

    if (cursorState == CursorState::NotExhausted || entry->getKillPending()) {
        return;
    }

    if (!remotesExhausted) {
        // The cursor still has open remote cursors that need to be cleaned up. Schedule for
        // deletion by the reaper thread by setting the kill pending flag.
        entry->setKillPending();
        return;
    }

    // The cursor is exhausted, is not already scheduled for deletion, and does not have any
    // remote cursor state left to clean up. We can delete the cursor right away.
    auto detachedCursor = detachCursor_inlock(nss, cursorId);
    invariantOK(detachedCursor.getStatus());

    // Deletion of the cursor can happen out of the lock.
    lk.unlock();
    detachedCursor.getValue().reset();
}
Пример #2
0
StatusWith<ClusterCursorManager::PinnedCursor> ClusterCursorManager::checkOutCursor(
    const NamespaceString& nss, CursorId cursorId) {
    // Read the clock out of the lock.
    const auto now = _clockSource->now();

    stdx::lock_guard<stdx::mutex> lk(_mutex);

    if (_inShutdown) {
        return Status(ErrorCodes::ShutdownInProgress,
                      "Cannot check out cursor as we are in the process of shutting down");
    }

    CursorEntry* entry = getEntry_inlock(nss, cursorId);
    if (!entry) {
        return cursorNotFoundStatus(nss, cursorId);
    }
    if (entry->getKillPending()) {
        return cursorNotFoundStatus(nss, cursorId);
    }
    std::unique_ptr<ClusterClientCursor> cursor = entry->releaseCursor();
    if (!cursor) {
        return cursorInUseStatus(nss, cursorId);
    }

    entry->setLastActive(now);

    // Note that pinning a cursor transfers ownership of the underlying ClusterClientCursor object
    // to the pin; the CursorEntry is left with a null ClusterClientCursor.
    return PinnedCursor(this, std::move(cursor), nss, cursorId);
}
Пример #3
0
void ClusterCursorManager::checkInCursor(std::unique_ptr<ClusterClientCursor> cursor,
                                         const NamespaceString& nss,
                                         CursorId cursorId,
                                         CursorState cursorState) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);

    invariant(cursor);

    CursorEntry* entry = getEntry_inlock(nss, cursorId);
    invariant(entry);

    entry->returnCursor(std::move(cursor));

    if (cursorState == CursorState::NotExhausted || entry->getKillPending()) {
        return;
    }

    // The cursor is exhausted, and the cursor doesn't already have a pending kill. Schedule for
    // deletion by setting the kill pending flag.
    entry->setKillPending();
}
Пример #4
0
StatusWith<ClusterCursorManager::PinnedCursor> ClusterCursorManager::checkOutCursor(
    const NamespaceString& nss, CursorId cursorId) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);

    CursorEntry* entry = getEntry_inlock(nss, cursorId);
    if (!entry) {
        return cursorNotFoundStatus(nss, cursorId);
    }
    if (entry->getKillPending()) {
        return cursorNotFoundStatus(nss, cursorId);
    }
    std::unique_ptr<ClusterClientCursor> cursor = entry->releaseCursor();
    if (!cursor) {
        return cursorInUseStatus(nss, cursorId);
    }

    entry->setLastActive(_clockSource->now());

    // Note that pinning a cursor transfers ownership of the underlying ClusterClientCursor object
    // to the pin; the CursorEntry is left with a null ClusterClientCursor.
    return PinnedCursor(this, std::move(cursor), nss, cursorId);
}