private static final int OPEN = 2;
// javadoc inherited
public void run() {
PooledConnection oldConnection = null;
PooledConnection newConnection = null;
long nextPollTime;
long systemTime;
// If we are keeping connections alive then we calculate the time
// at which we next have to poll a connection by adding the poll
// interval to the current time, otherwise we set it to the 'end
// of time'.
if (keepConnectionsAlive) {
nextPollTime = System.currentTimeMillis() + connectionPollInterval;
if (logger.isDebugEnabled()) {
logger.debug("Keeping connections alive:"
+ " poll interval is "
+ connectionPollInterval
+ " next poll time is " + nextPollTime);
}
} else {
nextPollTime = Long.MAX_VALUE;
}
boolean notify;
int action;
while (true) {
action = INVALID;
notify = false;
if (logger.isDebugEnabled()) {
logger.debug("Attempting to lock backgroundThread");
}
synchronized (this) {
if (terminateThread) {
if (logger.isDebugEnabled()) {
logger.debug("Terminating thread");
}
return;
}
// Protect the data structures.
if (logger.isDebugEnabled()) {
logger.debug("Attempting to lock freeConnections");
}
synchronized (freeConnections) {
// If we created a new connection last time around then
// add it to the free list.
if (newConnection != null) {
if (logger.isDebugEnabled()) {
logger.debug("Adding new connection");
}
freeConnections.add(newConnection);
newConnection = null;
notify = true;
}
int broken = brokenConnections.size();
int busy = busyConnections.size();
int free = freeConnections.size();
int total = busy + free;
if (logger.isDebugEnabled()) {
logger.debug("Status free:" + free
+ " busy: " + busy
+ " broken: " + broken);
}
// Remove all the broken connections.
for (int c = broken - 1; c >= 0; c -= 1) {
oldConnection = (PooledConnection) brokenConnections.remove(c);
if (logger.isDebugEnabled()) {
logger.debug("Discarding broken pooled connection "
+ oldConnection);
}
discardPooledConnection(oldConnection);
}
if (free > maxFreeConnections) {
if (logger.isDebugEnabled()) {
logger.debug("Above high water mark");
}
// Remove the last connection.
int last = free - 1;
oldConnection = (PooledConnection) freeConnections.remove(last);
// Remember to close the connection.
action = CLOSE;
} else if (total == maxConnections) {
if (logger.isDebugEnabled()) {
logger.debug("Maximum connections reached");
}
// Have reached the limit, there is nothing that
// can be done so go to sleep.
action = SLEEP;
} else if (free < minFreeConnections) {
if (logger.isDebugEnabled()) {
logger.debug("Below low water mark");
}
// Get another connection.
action = OPEN;
} else {
if (logger.isDebugEnabled()) {
logger.debug("Nothing to do");
}
action = SLEEP;
}
}
// Only go to sleep if we do not have to notify waiting
// threads.
boolean dropThrough = true;
systemTime = -1;
if (!notify && action == SLEEP) {
if (logger.isDebugEnabled()) {
logger.debug("Sleeping with nothing to do");
}
dropThrough = false;
try {
if (keepConnectionsAlive) {
// Calculate how long we have before the next
// poll time, if the poll time has already
// passed then don't wait.
systemTime = System.currentTimeMillis();
long timeout = nextPollTime - systemTime;
if (timeout > 0) {
if (logger.isDebugEnabled()) {
logger.debug(
"Keeping connections alive:" +
" timeout is " + timeout);
}
wait(timeout);
systemTime = -1;
}
} else {
wait();
}
} catch (InterruptedException ie) {
if (logger.isDebugEnabled()) {
logger.debug("Thread interrupted, exiting");
}
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Woken");
}
}
// If we are trying to keep the connections alive then
// check to see whether it is time to poll the connection.
if (keepConnectionsAlive &&
((systemTime = System.currentTimeMillis()) >=
nextPollTime)) {
if (logger.isDebugEnabled()) {
logger.debug("Keeping connections alive: poll " +
"time " + systemTime);
}
PooledConnection pooledConnection = null;
if (logger.isDebugEnabled()) {
logger.debug("Attempting to lock freeConnections");
}
synchronized (freeConnections) {
// We can only poll the connection if there is a free
// connection and we only need to poll the connection
// if there are no busy connections.
if (freeConnections.size() > 0
&& busyConnections.size() == 0) {
pooledConnection = getFreePooledConnection();
} else {
if (logger.isDebugEnabled()) {
logger.debug("Keeping connections alive:"
+ " nothing to do,"
+ " free connections "
+ freeConnections.size()
+ " busy connections "
+ busyConnections.size());
}
}
}
// Do this outside the monitor.
if (pooledConnection != null) {
if (logger.isDebugEnabled()) {
logger.debug(
"Keeping connections alive: polling");
}
SimplePooledConnection.LogicalConnection
sqlConnection = null;
boolean ok = false;
try {
// Get the SQL connection out of the pooled
// connection.
sqlConnection =
(SimplePooledConnection.
LogicalConnection)
pooledConnection.getConnection();
Statement stmt = sqlConnection.
createStatement();
String sql = "select revision from " +