Repository: commons-pool
Updated Branches:
  refs/heads/master 44e087d29 -> 12ba9290e


[POOL-336] GenericObjectPool's borrowObject lock if create() fails with
Error.

Project: http://git-wip-us.apache.org/repos/asf/commons-pool/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-pool/commit/12ba9290
Tree: http://git-wip-us.apache.org/repos/asf/commons-pool/tree/12ba9290
Diff: http://git-wip-us.apache.org/repos/asf/commons-pool/diff/12ba9290

Branch: refs/heads/master
Commit: 12ba9290e055c2cb86701530b66880e459794ebb
Parents: 44e087d
Author: Gary Gregory <ggreg...@apache.org>
Authored: Sat Dec 30 23:29:51 2017 -0700
Committer: Gary Gregory <ggreg...@apache.org>
Committed: Sat Dec 30 23:29:51 2017 -0700

----------------------------------------------------------------------
 src/changes/changes.xml                         |  5 ++
 .../commons/pool2/impl/GenericObjectPool.java   |  2 +-
 .../pool2/impl/TestGenericObjectPool.java       | 75 +++++++++++++++++++-
 3 files changed, 80 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-pool/blob/12ba9290/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 1e225fb..95460e0 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -43,6 +43,11 @@ The <action> type attribute can be add,update,fix,remove.
     <title>Apache Commons Pool Changes</title>
   </properties>
   <body>
+  <release version="2.5.1" date="2017-12-16" description="This is a 
maintenance release.">
+    <action dev="ggregory" issue="POOL-336" type="update" due-to="Wolfgang 
Glas">
+      GenericObjectPool's borrowObject lock if create() fails with Error.
+    </action>
+  </release>
   <release version="2.5.0" date="2017-12-16" description="This is a minor 
release, updating to Java 7.">
     <action dev="ggregory" issue="POOL-331" type="update">
       Update from Java 6 to 7.

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/12ba9290/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java 
b/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
index 02d8d02..a6a9f53 100644
--- a/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
+++ b/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
@@ -887,7 +887,7 @@ public class GenericObjectPool<T> extends 
BaseGenericObjectPool<T>
         final PooledObject<T> p;
         try {
             p = factory.makeObject();
-        } catch (final Exception e) {
+        } catch (final Throwable e) {
             createCount.decrementAndGet();
             throw e;
         } finally {

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/12ba9290/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java 
b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
index 915b4c4..0abc55b 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
@@ -2126,7 +2126,7 @@ public class TestGenericObjectPool extends 
TestBaseObjectPool {
                 Thread.sleep(_pause);
                 _pool.returnObject(obj);
                 postreturn = System.currentTimeMillis();
-            } catch (final Exception e) {
+            } catch (final Throwable e) {
                 _thrown = e;
             } finally{
                 ended = System.currentTimeMillis();
@@ -2635,6 +2635,79 @@ public class TestGenericObjectPool extends 
TestBaseObjectPool {
         }
     }
 
+    @Test
+    public void testErrorFactoryDoesNotBlockThreads() throws Exception {
+
+        final CreateErrorFactory factory = new CreateErrorFactory();
+        try (final GenericObjectPool<String> createFailFactoryPool = new 
GenericObjectPool<>(factory)) {
+
+            createFailFactoryPool.setMaxTotal(1);
+
+            // Try and borrow the first object from the pool
+            final WaitingTestThread thread1 = new 
WaitingTestThread(createFailFactoryPool, 0);
+            thread1.start();
+
+            // Wait for thread to reach semaphore
+            while (!factory.hasQueuedThreads()) {
+                Thread.sleep(200);
+            }
+
+            // Try and borrow the second object from the pool
+            final WaitingTestThread thread2 = new 
WaitingTestThread(createFailFactoryPool, 0);
+            thread2.start();
+            // Pool will not call factory since maximum number of object 
creations
+            // are already queued.
+
+            // Thread 2 will wait on an object being returned to the pool
+            // Give thread 2 a chance to reach this state
+            Thread.sleep(1000);
+
+            // Release thread1
+            factory.release();
+            // Pre-release thread2
+            factory.release();
+
+            // Both threads should now complete.
+            boolean threadRunning = true;
+            int count = 0;
+            while (threadRunning && count < 15) {
+                threadRunning = thread1.isAlive();
+                threadRunning = thread2.isAlive();
+                Thread.sleep(200);
+                count++;
+            }
+            Assert.assertFalse(thread1.isAlive());
+            Assert.assertFalse(thread2.isAlive());
+
+            Assert.assertTrue(thread1._thrown instanceof UnknownError);
+            Assert.assertTrue(thread2._thrown instanceof UnknownError);
+        }
+    }
+
+    private static class CreateErrorFactory extends 
BasePooledObjectFactory<String> {
+
+        private final Semaphore semaphore = new Semaphore(0);
+
+        @Override
+        public String create() throws Exception {
+            semaphore.acquire();
+            throw new UnknownError("wiggle");
+        }
+
+        @Override
+        public PooledObject<String> wrap(final String obj) {
+            return new DefaultPooledObject<>(obj);
+        }
+
+        public void release() {
+            semaphore.release();
+        }
+
+        public boolean hasQueuedThreads() {
+            return semaphore.hasQueuedThreads();
+        }
+    }
+
        private BasePooledObjectFactory<String> createBasePooledObjectfactory() 
{
                return new BasePooledObjectFactory<String>() {
                        @Override

Reply via email to