in src/main/java/org/apache/commons/pool3/impl/GenericObjectPool.java [282:369]
public T borrowObject(final Duration maxWaitDuration) throws E {
assertOpen();
final Instant startInstant = Instant.now();
final boolean negativeDuration = maxWaitDuration.isNegative();
Duration remainingWaitDuration = maxWaitDuration;
final AbandonedConfig ac = this.abandonedConfig;
if (ac != null && ac.getRemoveAbandonedOnBorrow() && getNumIdle() < 2 && getNumActive() > getMaxTotal() - 3) {
removeAbandoned(ac);
}
PooledObject<T> p = null;
// Get local copy of current config so it is consistent for entire
// method execution
final boolean blockWhenExhausted = getBlockWhenExhausted();
boolean create;
while (p == null) {
remainingWaitDuration = maxWaitDuration.minus(durationSince(startInstant));
create = false;
p = idleObjects.pollFirst();
if (p == null) {
p = create(remainingWaitDuration);
if (!PooledObject.isNull(p)) {
create = true;
}
}
if (blockWhenExhausted) {
if (PooledObject.isNull(p)) {
try {
remainingWaitDuration = maxWaitDuration.minus(durationSince(startInstant));
p = negativeDuration ? idleObjects.takeFirst() : idleObjects.pollFirst(maxWaitDuration);
} catch (final InterruptedException e) {
// Don't surface exception type of internal locking mechanism.
throw cast(e);
}
}
if (PooledObject.isNull(p)) {
throw new NoSuchElementException(appendStats("Timeout waiting for idle object, borrowMaxWaitDuration=" + remainingWaitDuration));
}
} else if (PooledObject.isNull(p)) {
throw new NoSuchElementException(appendStats("Pool exhausted"));
}
if (!p.allocate()) {
p = null;
}
if (!PooledObject.isNull(p)) {
try {
factory.activateObject(p);
} catch (final Exception e) {
try {
destroy(p, DestroyMode.NORMAL);
} catch (final Exception ignored) {
// ignored - activation failure is more important
}
p = null;
if (create) {
final NoSuchElementException nsee = new NoSuchElementException(appendStats("Unable to activate object"));
nsee.initCause(e);
throw nsee;
}
}
if (!PooledObject.isNull(p) && getTestOnBorrow()) {
boolean validate = false;
Throwable validationThrowable = null;
try {
validate = factory.validateObject(p);
} catch (final Throwable t) {
PoolUtils.checkRethrow(t);
validationThrowable = t;
}
if (!validate) {
try {
destroy(p, DestroyMode.NORMAL);
destroyedByBorrowValidationCount.incrementAndGet();
} catch (final Exception ignored) {
// ignored - validation failure is more important
}
p = null;
if (create) {
final NoSuchElementException nsee = new NoSuchElementException(appendStats("Unable to validate object"));
nsee.initCause(validationThrowable);
throw nsee;
}
}
}
}
}
updateStatsBorrow(p, durationSince(startInstant));
return p.getObject();
}