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: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org