Search in sources :

Example 1 with CriticalSection

use of jetbrains.exodus.core.execution.locks.CriticalSection in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method releaseTransaction.

/**
 * Release transaction that was acquired in a thread with specified permits.
 */
void releaseTransaction(@NotNull final Thread thread, final int permits) {
    try (CriticalSection ignored = criticalSection.enter()) {
        int currentThreadPermits = getThreadPermits(thread);
        if (permits > currentThreadPermits) {
            throw new ExodusException("Can't release more permits than it was acquired");
        }
        acquiredPermits -= permits;
        currentThreadPermits -= permits;
        if (currentThreadPermits == 0) {
            threadPermits.remove(thread);
        } else {
            threadPermits.put(thread, currentThreadPermits);
        }
        notifyNextWaiters();
    }
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection) ExodusException(jetbrains.exodus.ExodusException)

Example 2 with CriticalSection

use of jetbrains.exodus.core.execution.locks.CriticalSection in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method acquireTransaction.

/**
 * Acquire transaction with a single permit in a thread. Transactions are acquired reentrantly, i.e.
 * with respect to transactions already acquired in the thread.
 *
 * @return the number of acquired permits, identically equal to 1.
 */
int acquireTransaction(@NotNull final Thread thread) {
    try (CriticalSection ignored = criticalSection.enter()) {
        final int currentThreadPermits = getThreadPermitsToAcquire(thread);
        waitForPermits(thread, currentThreadPermits > 0 ? nestedQueue : regularQueue, 1, currentThreadPermits);
    }
    return 1;
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection)

Example 3 with CriticalSection

use of jetbrains.exodus.core.execution.locks.CriticalSection in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method downgradeTransaction.

/**
 * Downgrade transaction (making it holding only 1 permit) that was acquired in a thread with specified permits.
 */
void downgradeTransaction(@NotNull final Thread thread, final int permits) {
    if (permits > 1) {
        try (CriticalSection ignored = criticalSection.enter()) {
            int currentThreadPermits = getThreadPermits(thread);
            if (permits > currentThreadPermits) {
                throw new ExodusException("Can't release more permits than it was acquired");
            }
            acquiredPermits -= (permits - 1);
            currentThreadPermits -= (permits - 1);
            threadPermits.put(thread, currentThreadPermits);
            notifyNextWaiters();
        }
    }
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection) ExodusException(jetbrains.exodus.ExodusException)

Example 4 with CriticalSection

use of jetbrains.exodus.core.execution.locks.CriticalSection in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method acquireExclusiveTransaction.

/**
 * Acquire exclusive transaction in a thread. Transactions are acquired reentrantly, i.e. with respect
 * to transactions already acquired in the thread.
 * NB! Nested transaction is never acquired as exclusive.
 *
 * @return the number of acquired permits.
 */
int acquireExclusiveTransaction(@NotNull final Thread thread) {
    try (CriticalSection ignored = criticalSection.enter()) {
        final int currentThreadPermits = getThreadPermitsToAcquire(thread);
        // if there are no permits acquired in the thread then we can acquire exclusive txn, i.e. all available permits
        if (currentThreadPermits == 0) {
            waitForPermits(thread, regularQueue, availablePermits, 0);
            return availablePermits;
        }
        waitForPermits(thread, nestedQueue, 1, currentThreadPermits);
    }
    return 1;
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection)

Example 5 with CriticalSection

use of jetbrains.exodus.core.execution.locks.CriticalSection in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method tryAcquireExclusiveTransaction.

/**
 * Wait for exclusive permit during a timeout in milliseconds.
 *
 * @return number of acquired permits if > 0
 */
private int tryAcquireExclusiveTransaction(@NotNull final Thread thread, final int timeout) {
    long nanos = TimeUnit.MILLISECONDS.toNanos(timeout);
    try (CriticalSection ignored = criticalSection.enter()) {
        if (getThreadPermits(thread) > 0) {
            throw new ExodusException("Exclusive transaction can't be nested");
        }
        final Condition condition = criticalSection.newCondition();
        final long currentOrder = acquireOrder++;
        regularQueue.put(currentOrder, condition);
        while (acquiredPermits > 0 || regularQueue.firstKey() != currentOrder) {
            try {
                nanos = condition.awaitNanos(nanos);
                if (nanos < 0) {
                    break;
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        if (acquiredPermits == 0 && regularQueue.firstKey() == currentOrder) {
            regularQueue.pollFirstEntry();
            acquiredPermits = availablePermits;
            threadPermits.put(thread, availablePermits);
            return availablePermits;
        }
        regularQueue.remove(currentOrder);
        notifyNextWaiters();
    }
    return 0;
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection) Condition(java.util.concurrent.locks.Condition) ExodusException(jetbrains.exodus.ExodusException)

Aggregations

CriticalSection (jetbrains.exodus.core.execution.locks.CriticalSection)5 ExodusException (jetbrains.exodus.ExodusException)3 Condition (java.util.concurrent.locks.Condition)1