Beispiel #1
0
LockResult LockerImpl<IsForMMAPV1>::_lockGlobalBegin(LockMode mode, Milliseconds timeout) {
    dassert(isLocked() == (_modeForTicket != MODE_NONE));
    if (_modeForTicket == MODE_NONE) {
        const bool reader = isSharedLockMode(mode);
        auto holder = ticketHolders[mode];
        if (holder) {
            _clientState.store(reader ? kQueuedReader : kQueuedWriter);
            if (timeout == Milliseconds::max()) {
                holder->waitForTicket();
            } else if (!holder->waitForTicketUntil(Date_t::now() + timeout)) {
                _clientState.store(kInactive);
                return LOCK_TIMEOUT;
            }
        }
        _clientState.store(reader ? kActiveReader : kActiveWriter);
        _modeForTicket = mode;
    }
    const LockResult result = lockBegin(resourceIdGlobal, mode);
    if (result == LOCK_OK)
        return LOCK_OK;

    // Currently, deadlock detection does not happen inline with lock acquisition so the only
    // unsuccessful result that the lock manager would return is LOCK_WAITING.
    invariant(result == LOCK_WAITING);

    return result;
}
Beispiel #2
0
LockResult LockerImpl<IsForMMAPV1>::_acquireTicket(OperationContext* opCtx,
                                                   LockMode mode,
                                                   Date_t deadline) {
    const bool reader = isSharedLockMode(mode);
    auto holder = shouldAcquireTicket() ? ticketHolders[mode] : nullptr;
    if (holder) {
        _clientState.store(reader ? kQueuedReader : kQueuedWriter);

        // If the ticket wait is interrupted, restore the state of the client.
        auto restoreStateOnErrorGuard = MakeGuard([&] { _clientState.store(kInactive); });
        if (deadline == Date_t::max()) {
            holder->waitForTicket(opCtx);
        } else if (!holder->waitForTicketUntil(opCtx, deadline)) {
            return LOCK_TIMEOUT;
        }
        restoreStateOnErrorGuard.Dismiss();
    }
    _clientState.store(reader ? kActiveReader : kActiveWriter);
    return LOCK_OK;
}
Beispiel #3
0
LockResult LockerImpl::_acquireTicket(OperationContext* opCtx, LockMode mode, Date_t deadline) {
    const bool reader = isSharedLockMode(mode);
    auto holder = shouldAcquireTicket() ? ticketHolders[mode] : nullptr;
    if (holder) {
        _clientState.store(reader ? kQueuedReader : kQueuedWriter);

        if (_maxLockTimeout && !_uninterruptibleLocksRequested) {
            deadline = std::min(deadline, Date_t::now() + _maxLockTimeout.get());
        }

        // If the ticket wait is interrupted, restore the state of the client.
        auto restoreStateOnErrorGuard = MakeGuard([&] { _clientState.store(kInactive); });

        OperationContext* interruptible = _uninterruptibleLocksRequested ? nullptr : opCtx;
        if (deadline == Date_t::max()) {
            holder->waitForTicket(interruptible);
        } else if (!holder->waitForTicketUntil(interruptible, deadline)) {
            return LOCK_TIMEOUT;
        }
        restoreStateOnErrorGuard.Dismiss();
    }
    _clientState.store(reader ? kActiveReader : kActiveWriter);
    return LOCK_OK;
}
void TicketHolder::waitForTicket(OperationContext* opCtx) {
    waitForTicketUntil(opCtx, Date_t::max());
}