in src/main/java/org/apache/commons/pool3/impl/GenericKeyedObjectPool.java [1456:1530]
public void returnObject(final K key, final T obj) {
final ObjectDeque<T> objectDeque = poolMap.get(key);
if (objectDeque == null) {
throw new IllegalStateException("No keyed pool found under the given key.");
}
final PooledObject<T> p = objectDeque.getAllObjects().get(new IdentityWrapper<>(obj));
if (PooledObject.isNull(p)) {
throw new IllegalStateException("Returned object not currently part of this pool");
}
markReturningState(p);
final Duration activeTime = p.getActiveDuration();
try {
if (getTestOnReturn() && !factory.validateObject(key, p)) {
try {
destroy(key, p, true, DestroyMode.NORMAL);
} catch (final Exception e) {
swallowException(e);
}
whenWaitersAddObject(key, objectDeque.idleObjects);
return;
}
try {
factory.passivateObject(key, p);
} catch (final Exception e1) {
swallowException(e1);
try {
destroy(key, p, true, DestroyMode.NORMAL);
} catch (final Exception e) {
swallowException(e);
}
whenWaitersAddObject(key, objectDeque.idleObjects);
return;
}
if (!p.deallocate()) {
throw new IllegalStateException("Object has already been returned to this pool");
}
final int maxIdle = getMaxIdlePerKey();
final LinkedBlockingDeque<PooledObject<T>> idleObjects = objectDeque.getIdleObjects();
if (isClosed() || maxIdle > -1 && maxIdle <= idleObjects.size()) {
try {
destroy(key, p, true, DestroyMode.NORMAL);
} catch (final Exception e) {
swallowException(e);
}
} else {
if (getLifo()) {
idleObjects.addFirst(p);
} else {
idleObjects.addLast(p);
}
if (isClosed()) {
// Pool closed while object was being added to idle objects.
// Make sure the returned object is destroyed rather than left
// in the idle object pool (which would effectively be a leak)
clear(key);
}
}
} finally {
if (hasBorrowWaiters()) {
reuseCapacity();
}
updateStatsReturn(activeTime);
}
}