public V getResource(K key, final long maxWaitMillis, Object... additionalArgs) throws OLockException {
// First, get permission to take or create a resource
try {
if (!sem.tryAcquire(maxWaitMillis, TimeUnit.MILLISECONDS))
throw new OLockException("No more resources available in pool. Requested resource: " + key);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new OInterruptedException(e);
}
V res;
do {
// POP A RESOURCE
res = resources.poll();
if (res != null) {
// TRY TO REUSE IT
if (listener.reuseResource(key, additionalArgs, res)) {
// OK: REUSE IT
break;
} else
res = null;
// UNABLE TO REUSE IT: THE RESOURE WILL BE DISCARDED AND TRY WITH THE NEXT ONE, IF ANY
}
} while (!resources.isEmpty());
// NO AVAILABLE RESOURCES: CREATE A NEW ONE
try {
if (res == null) {
res = listener.createNewResource(key, additionalArgs);
created++;
}
return res;
} catch (RuntimeException e) {
sem.release();
// PROPAGATE IT
throw e;
} catch (Exception e) {
sem.release();
throw new OLockException("Error on creation of the new resource in the pool", e);
}
}