Author: fhanik
Date: Wed Jan 19 21:25:08 2011
New Revision: 1060998
URL: http://svn.apache.org/viewvc?rev=1060998&view=rev
Log:
https://issues.apache.org/bugzilla/show_bug.cgi?id=50613
Fix concurrency bug around size calculation for the pool
Added:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestSizePreservation.java
(with props)
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=1060998&r1=1060997&r2=1060998&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
Wed Jan 19 21:25:08 2011
@@ -545,7 +545,7 @@ public class ConnectionPool {
// we could have threads stuck in idle.poll(timeout) that will never be
// notified
if (waitcount.get() > 0) {
- idle.offer(new PooledConnection(poolProperties, this));
+ idle.offer(create(true));
}
}
@@ -637,7 +637,7 @@ public class ConnectionPool {
*/
protected PooledConnection createConnection(long now, PooledConnection
notUsed, String username, String password) throws SQLException {
//no connections where available we'll create one
- PooledConnection con = create();
+ PooledConnection con = create(false);
if (username!=null) con.getAttributes().put(con.PROP_USER, username);
if (password!=null) con.getAttributes().put(con.PROP_PASSWORD,
password);
boolean error = false;
@@ -984,7 +984,8 @@ public class ConnectionPool {
* Create a new pooled connection object. Not connected nor validated.
* @return a pooled connection object
*/
- protected PooledConnection create() {
+ protected PooledConnection create(boolean incrementCounter) {
+ if (incrementCounter) size.incrementAndGet();
PooledConnection con = new PooledConnection(getPoolProperties(), this);
return con;
}
Added:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestSizePreservation.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestSizePreservation.java?rev=1060998&view=auto
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestSizePreservation.java
(added)
+++
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestSizePreservation.java
Wed Jan 19 21:25:08 2011
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.jdbc.test;
+
+import java.sql.Connection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.apache.tomcat.jdbc.pool.PoolConfiguration;
+import org.apache.tomcat.jdbc.test.driver.Driver;
+/**
+ *
+ * @author Jeremy Norris
+ * https://issues.apache.org/bugzilla/show_bug.cgi?id=50613
+ *
+ */
+public class TestSizePreservation extends TestCase {
+
+ protected volatile DataSource ds = null;
+
+ public TestSizePreservation() {
+ }
+
+ private void initSimplePoolProperties() {
+ PoolConfiguration p = new DefaultProperties();
+ ds = new org.apache.tomcat.jdbc.pool.DataSource();
+ ds.setPoolProperties(p);
+
+ ds.getPoolProperties().setDriverClassName(Driver.class.getName());
+ ds.getPoolProperties().setUrl(Driver.url);
+ ds.getPoolProperties().setFairQueue(true);
+ ds.getPoolProperties().setJmxEnabled(false);
+ ds.getPoolProperties().setTestWhileIdle(true);
+ ds.getPoolProperties().setTestOnBorrow(false);
+ ds.getPoolProperties().setTestOnReturn(false);
+ ds.getPoolProperties().setValidationInterval(30000);
+ ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(30000);
+ ds.getPoolProperties().setInitialSize(100);
+ ds.getPoolProperties().setMaxActive(100);
+ ds.getPoolProperties().setMinIdle(0);
+ ds.getPoolProperties().setMaxIdle(0);
+ ds.getPoolProperties().setMaxWait(10000);
+ ds.getPoolProperties().setRemoveAbandonedTimeout(10);
+ ds.getPoolProperties().setMinEvictableIdleTimeMillis(10000);
+ ds.getPoolProperties().setLogAbandoned(false);
+ ds.getPoolProperties().setRemoveAbandoned(false);
+ ds.getPoolProperties().setUseLock(true);
+ }
+
+ private void initEvictingPool() {
+ initSimplePoolProperties();
+ ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(25);
+ ds.getPoolProperties().setMinEvictableIdleTimeMillis(750);
+ ds.getPoolProperties().setRemoveAbandoned(true);
+ ds.getPoolProperties().setRemoveAbandonedTimeout(1);
+ }
+
+ public void testSimple() throws Exception {
+ initSimplePoolProperties();
+ common();
+ ds.close(true);
+ Driver.reset();
+ }
+
+ public void testEvicting() throws Exception {
+ initEvictingPool();
+ common();
+ ds.close(true);
+ Driver.reset();
+ }
+
+ private void common() throws Exception {
+ ds.getConnection().close();
+ final int iterations = 1000;
+ final AtomicInteger loopcount = new AtomicInteger(0);
+ final Runnable run = new Runnable() {
+ public void run() {
+ try {
+ while (loopcount.incrementAndGet() < iterations) {
+ Connection c = ds.getConnection();
+ Thread.sleep(1000);
+ c.close();
+ }
+ } catch (Exception x) {
+ x.printStackTrace();
+ }
+ }
+ };
+ Thread[] threads = new Thread[200];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new Thread(run);
+ }
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].start();
+ }
+ try {
+ while (loopcount.get() < iterations) {
+ Thread.sleep(250);
+ }
+ } catch (Exception x) {
+ loopcount.set(iterations); // stops the test
+ x.printStackTrace();
+ }
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].join();
+ }
+ System.out.println("Pool size:"+ds.getPool().getSize());
+ assertTrue("Size validity check: ", ds.getPool().getSize() >= 0);
+ }
+
+}
Propchange:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestSizePreservation.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]