public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException
{
subject = (subject == null) ? defaultSubject : subject;
cri = (cri == null) ? defaultCri : cri;
ConnectionListener cl = null;
boolean verifyConnectionListener = true;
long startWait = System.currentTimeMillis();
if (getAvailableConnections() > 0)
{
if (shutdown.get())
throw new RetryableUnavailableException("The pool has been shutdown");
cl = cls.peek();
if (cl != null)
{
try
{
cl = cls.poll(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS);
}
catch (InterruptedException ie)
{
long end = System.currentTimeMillis() - startWait;
throw new ResourceException("Interrupted while requesting connection! Waited " + end + " ms");
}
}
else
{
try
{
// No, the pool was empty, so we have to make a new one.
cl = createConnectionEventListener(subject, cri);
// Started is atomic, so pool filler won't be scheduled twice
if (!started.getAndSet(true))
{
if (poolConfiguration.getMinSize() > 0)
PoolFiller.fillPool(this);
}
if (trace)
log.trace("supplying new ManagedConnection: " + cl);
verifyConnectionListener = false;
}
catch (Throwable t)
{
log.warn("Throwable while attempting to get a new connection: " + cl, t);
JBossResourceException.rethrowAsResourceException("Unexpected throwable while trying " +
"to create a connection: " + cl, t);
}
}
}
else
{
try
{
cl = cls.poll(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS);
if (shutdown.get())
throw new RetryableUnavailableException("The pool has been shutdown");
}
catch (InterruptedException ie)
{
if (!poolConfiguration.isUseFastFail())
{
throw new ResourceException("No ManagedConnections available within configured blocking timeout ( "
+ poolConfiguration.getBlockingTimeout() + " [ms] )");
}
else
{
if (trace)
log.trace("Fast failing for connection attempt. No more attempts will be made to " +
"acquire connection from pool and a new connection will be created immeadiately");
try
{
cl = createConnectionEventListener(subject, cri);
// Started is atomic, so pool filler won't be scheduled twice
if (!started.getAndSet(true))
{
if (poolConfiguration.getMinSize() > 0)
PoolFiller.fillPool(this);
}
if (trace)
log.trace("supplying new ManagedConnection: " + cl);
verifyConnectionListener = false;
}
catch (Throwable t)
{
log.warn("Throwable while attempting to get a new connection: " + cl, t);
JBossResourceException.rethrowAsResourceException("Unexpected throwable while trying to " +
"create a connection: " + cl, t);
}
}
}
}
// Register the connection listener
checkedOut.add(cl);
// Update max used connections
int size = maxSize - permits.size();
if (size > maxUsedConnections.get())
maxUsedConnections.set(size);
if (!verifyConnectionListener)
{
// Register the connection listener with permits
permits.put(cl, cl);
// Return connection listener
return cl;
}
else
{
try
{
Object matchedMC =
mcf.matchManagedConnections(Collections.singleton(cl.getManagedConnection()), subject, cri);
if (matchedMC != null)
{
if (trace)
log.trace("supplying ManagedConnection from pool: " + cl);