Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Simplify DefaultConnectionPool.OpenConcurrencyLimiter.tryLock
When locking for the purpose of using the wait/signal approach,
one does not have to account the time spent acquiring the lock
towards the timeout. While doing so may reduce the
non-deterministic duration by which a timeout is exceeded
by any implementation of a timeout, such overtime is usually negligible,
unless the lock is highly contended and/or checking the condition
before starting to wait is time-consuming.

The Java SE example for `java.util.concurrent.locks.Condition.awaitNanos`
ignores the time spent acquiring the lock. Doing so potentially reduces
responsiveness to timeouts, but does not
affect other performance characteristics, so I believe such simplification
is worth it and I should have taken this path initially.

JAVA-3927
  • Loading branch information
stIncMale committed May 1, 2021
commit 3bce9e72ede62ca29cef3730d6d525f303377fcc
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ private PooledConnection acquirePermitOrGetAvailableOpenedConnection(final boole
throws MongoTimeoutException {
PooledConnection availableConnection = null;
boolean expressedDesireToGetAvailableConnection = false;
tryLock(timeout);
lockInterruptibly(lock);
try {
if (tryGetAvailable) {
/* An attempt to get an available opened connection from the pool (must be done while holding the lock)
Expand Down Expand Up @@ -935,26 +935,13 @@ void tryHandOverOrRelease(final UsageTrackingInternalConnection openConnection)
}
}

/**
* @param timeout If {@linkplain Timeout#isInfinite() infinite},
* then the lock is {@linkplain Lock#lockInterruptibly() acquired interruptibly}.
*/
private void tryLock(final Timeout timeout) throws MongoTimeoutException {
boolean success;
private void lockInterruptibly(final Lock lock) throws MongoInterruptedException {
try {
if (timeout.isInfinite()) {
lock.lockInterruptibly();
success = true;
} else {
success = lock.tryLock(timeout.remaining(NANOSECONDS), NANOSECONDS);
}
lock.lockInterruptibly();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new MongoInterruptedException(null, e);
}
if (!success) {
throw createTimeoutException(timeout);
}
}

/**
Expand Down