You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2009/05/18 22:37:49 UTC
svn commit: r776085 -
/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
Author: markt
Date: Mon May 18 20:37:49 2009
New Revision: 776085
URL: http://svn.apache.org/viewvc?rev=776085&view=rev
Log:
Fixes for POOL-136. Make syncs consistent.
Modified:
commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
Modified: commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=776085&r1=776084&r2=776085&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java (original)
+++ commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java Mon May 18 20:37:49 2009
@@ -946,7 +946,16 @@
public Object borrowObject(Object key) throws Exception {
long starttime = System.currentTimeMillis();
Latch latch = new Latch(key);
+ byte whenExhaustedAction;
+ long maxWait;
synchronized (this) {
+ // Get local copy of current config. Can't sync when used later as
+ // it can result in a deadlock. Has the added advantage that config
+ // is consistent for entire method execution
+ whenExhaustedAction = _whenExhaustedAction;
+ maxWait = _maxWait;
+
+ // Add this request to the queue
_allocationQueue.add(latch);
allocate();
}
@@ -962,7 +971,7 @@
// allow new object to be created
} else {
// the pool is exhausted
- switch(_whenExhaustedAction) {
+ switch(whenExhaustedAction) {
case WHEN_EXHAUSTED_GROW:
// allow new object to be created
break;
@@ -974,13 +983,13 @@
case WHEN_EXHAUSTED_BLOCK:
try {
synchronized (latch) {
- if(_maxWait <= 0) {
+ if(maxWait <= 0) {
latch.wait();
} else {
// this code may be executed again after a notify then continue cycle
// so, need to calculate the amount of time to wait
final long elapsed = (System.currentTimeMillis() - starttime);
- final long waitTime = _maxWait - elapsed;
+ final long waitTime = maxWait - elapsed;
if (waitTime > 0)
{
latch.wait(waitTime);
@@ -991,13 +1000,13 @@
Thread.currentThread().interrupt();
throw e;
}
- if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {
+ if(maxWait > 0 && ((System.currentTimeMillis() - starttime) >= maxWait)) {
throw new NoSuchElementException("Timeout waiting for idle object");
} else {
continue; // keep looping
}
default:
- throw new IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + " not recognized.");
+ throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
}
}
}
@@ -1501,9 +1510,18 @@
* @throws Exception when there is a problem evicting idle objects.
*/
public void evict() throws Exception {
- // Initialize key to last key value
Object key = null;
+ boolean testWhileIdle;
+ long minEvictableIdleTimeMillis;
+
synchronized (this) {
+ // Get local copy of current config. Can't sync when used later as
+ // it can result in a deadlock. Has the added advantage that config
+ // is consistent for entire method execution
+ testWhileIdle = _testWhileIdle;
+ minEvictableIdleTimeMillis = _minEvictableIdleTimeMillis;
+
+ // Initialize key to last key value
if (_evictionKeyCursor != null &&
_evictionKeyCursor._lastReturned != null) {
key = _evictionKeyCursor._lastReturned.value();
@@ -1582,12 +1600,12 @@
}
boolean removeObject=false;
- if((_minEvictableIdleTimeMillis > 0) &&
+ if((minEvictableIdleTimeMillis > 0) &&
(System.currentTimeMillis() - pair.tstamp >
- _minEvictableIdleTimeMillis)) {
+ minEvictableIdleTimeMillis)) {
removeObject=true;
}
- if(_testWhileIdle && removeObject == false) {
+ if(testWhileIdle && removeObject == false) {
boolean active = false;
try {
_factory.activateObject(key,pair.value);
@@ -1778,7 +1796,7 @@
return buf.toString();
}
- private int getNumTests() {
+ private synchronized int getNumTests() {
if(_numTestsPerEvictionRun >= 0) {
return _numTestsPerEvictionRun;
} else {
@@ -1837,27 +1855,35 @@
private int internalProcessingCount = 0;
void incrementActiveCount() {
- _totalActive++;
+ synchronized (GenericKeyedObjectPool.this) {
+ _totalActive++;
+ }
activeCount++;
}
void decrementActiveCount() {
- _totalActive--;
+ synchronized (GenericKeyedObjectPool.this) {
+ _totalActive--;
+ }
if (activeCount > 0) {
activeCount--;
}
}
void incrementInternalProcessingCount() {
- _totalInternalProcessing++;
+ synchronized (GenericKeyedObjectPool.this) {
+ _totalInternalProcessing++;
+ }
internalProcessingCount++;
}
void decrementInternalProcessingCount() {
- _totalInternalProcessing--;
+ synchronized (GenericKeyedObjectPool.this) {
+ _totalInternalProcessing--;
+ }
internalProcessingCount--;
}
-}
+ }
/**
* A simple "struct" encapsulating an object instance and a timestamp.