}
}
private PooledConnection waitForConnection(long timeout, TimeUnit unit) throws ConnectionException, TimeoutException {
if (timeout == 0)
throw new TimeoutException();
long start = System.nanoTime();
long remaining = timeout;
do {
try {
awaitAvailableConnection(remaining, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// If we're interrupted fine, check if there is a connection available but stop waiting otherwise
timeout = 0; // this will make us stop the loop if we don't get a connection right away
}
if (isClosed())
throw new ConnectionException(host.getSocketAddress(), "Pool is shutdown");
PooledConnection connection = connectionRef.get();
// If we race with shutdown, connection could be null. In that case we just loop and we'll throw on the next
// iteration anyway
if (connection != null) {
while (true) {
int inFlight = connection.inFlight.get();
if (inFlight >= Math.min(connection.maxAvailableStreams(),
options().getMaxSimultaneousRequestsPerHostThreshold(hostDistance)))
break;
if (connection.inFlight.compareAndSet(inFlight, inFlight + 1))
return connection;
}
}
remaining = timeout - Cluster.timeSince(start, unit);
} while (remaining > 0);
throw new TimeoutException();
}