bloritsch 01/03/16 07:14:14 Modified: src/java/org/apache/avalon/util Lock.java src/java/org/apache/avalon/util/datasource JdbcConnectionPool.java JdbcDataSource.java Log: Made Lock atomic in its actions. Made JdbcDatasource a bit simpler using the lock interface. Revision Changes Path 1.2 +26 -26 jakarta-avalon/src/java/org/apache/avalon/util/Lock.java Index: Lock.java =================================================================== RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/Lock.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Lock.java 2001/02/24 03:59:37 1.1 +++ Lock.java 2001/03/16 15:14:00 1.2 @@ -40,20 +40,20 @@ synchronized( this ) { theLock = locks.get( key ); - } - if( null == theLock ) - { - locks.put( key, getCallerId() ); - return true; - } - else if( getCallerId() == theLock ) - { - return true; - } - else - { - return false; + if( null == theLock ) + { + locks.put( key, getCallerId() ); + return true; + } + else if( getCallerId() == theLock ) + { + return true; + } + else + { + return false; + } } } @@ -63,20 +63,20 @@ synchronized( this ) { theLock = locks.get( key ); - } - if( null == theLock ) - { - return true; - } - else if( getCallerId() == theLock ) - { - locks.remove( key ); - return true; - } - else - { - return false; + if( null == theLock ) + { + return true; + } + else if( getCallerId() == theLock ) + { + locks.remove( key ); + return true; + } + else + { + return false; + } } } 1.6 +61 -141 jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcConnectionPool.java Index: JdbcConnectionPool.java =================================================================== RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcConnectionPool.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- JdbcConnectionPool.java 2001/03/14 16:30:15 1.5 +++ JdbcConnectionPool.java 2001/03/16 15:14:07 1.6 @@ -19,13 +19,14 @@ import org.apache.avalon.Poolable; import org.apache.avalon.Recyclable; import org.apache.avalon.util.pool.Pool; +import org.apache.avalon.util.Lock; /** * The Pool implementation for JdbcConnections. It uses a background * thread to manage the number of SQL Connections. * * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a> - * @version CVS $Revision: 1.5 $ $Date: 2001/03/14 16:30:15 $ + * @version CVS $Revision: 1.6 $ $Date: 2001/03/16 15:14:07 $ */ public class JdbcConnectionPool extends AbstractLoggable @@ -34,18 +35,18 @@ private final String m_dburl; private final String m_username; private final String m_password; - private final int m_min; private final int m_max; private final boolean m_autoCommit; - private int m_currentCount; private List m_active = new ArrayList(); private List m_ready = new ArrayList(); - private boolean m_monitoring = true; + private boolean m_initialized = false; + private boolean m_disposed = false; + private Lock m_lock = new Lock(); + private Thread m_initThread; public JdbcConnectionPool( final String url, final String username, final String password, - final int min, final int max, final boolean autoCommit ) { @@ -53,23 +54,12 @@ m_username = username; m_password = password; - if( min < 0 ) + if( max < 1 ) { - getLogger().warn( "Minumum number of connections specified is " + - "less than 0, using 0" ); - m_min = 0; - } - else - { - m_min = min; - } - - if( ( max < min ) || ( max < 1 ) ) - { getLogger().warn( "Maximum number of connections specified must be at " + "least 1 and must be greater than the minumum number " + "of connections" ); - m_max = ( min > 1 ) ? min : 1; + m_max = 1; } else { @@ -81,16 +71,8 @@ public void init() { - for( int i = 0; i < m_min; i++ ) - { - try { - m_ready.add( createJdbcConnection() ); - } catch (SQLException se) { - getLogger().error( "Could not create connection to database", se ); - } - } - - new Thread( this ).start(); + m_initThread = new Thread( this ); + m_initThread.start(); } private JdbcConnection createJdbcConnection() @@ -113,8 +95,6 @@ connection.setLogger(getLogger()); } - m_currentCount++; - getLogger().debug( "JdbcConnection object created" ); return connection; } @@ -123,75 +103,45 @@ { getLogger().debug( "JdbcConnection object recycled" ); obj.recycle(); - m_currentCount--; } public Poolable get() throws Exception { - Poolable obj = null; - final int size; - - synchronized (m_ready) - { - size = m_ready.size(); - } - - if( 0 == size ) - { - if( m_currentCount < m_max ) + if (!m_initialized) { + if (m_initThread == null) { - obj = createJdbcConnection(); - - synchronized(m_active) - { - m_active.add( obj ); - } + throw new IllegalStateException("You cannot get a Connection before the pool is initialized"); } else { -/* - long start = new Date().getTime(); - long end = start + 500; // timeout is 500 ms - - while (obj == null && new Date().getTime() < end) - { -*/ - synchronized (m_ready) - { -/* - m_ready.wait((end - start)/2); -*/ - if (m_ready.size() > 0) - { - obj = (Poolable)m_ready.remove(0); - - synchronized (m_active) - { - m_active.add(obj); - } - } - } -/* - } -*/ - if (obj == null) - throw new SQLException("There are no more Connections available"); + m_initThread.join(); } } + + if (!m_disposed) { + throw new IllegalStateException("You cannot get a Connection after the pool is disposed"); + } + + m_lock.lock(m_ready); + Poolable obj = null; + final int size; + + if( 0 == m_ready.size() ) + { + throw new SQLException("There are no more Connections available"); + } else { - synchronized (m_ready) - { - obj = (Poolable)m_ready.remove( 0 ); - } + obj = (Poolable)m_ready.remove( 0 ); - synchronized (m_active) - { - m_active.add( obj ); - } + m_lock.lock(m_active); + m_active.add( obj ); + m_lock.unlock(m_active); } + m_lock.unlock(m_ready); + if (((Connection)obj).getAutoCommit() != m_autoCommit) { ((Connection)obj).setAutoCommit(m_autoCommit); } @@ -204,86 +154,56 @@ public void put( final Poolable obj ) { - synchronized (m_active) + if (! m_initialized) { - m_active.remove( obj ); + throw new IllegalStateException("You cannot return an object to an uninitialized pool"); } - if( m_monitoring ) + m_lock.lock(m_active); + m_active.remove( obj ); + + if( ! m_disposed ) { - synchronized (m_ready) - { - m_ready.add( obj ); - m_ready.notify(); - } + m_lock.lock(m_ready); + m_ready.add( obj ); + m_ready.notify(); + m_lock.unlock(m_ready); } else { recycle((Recyclable) obj); } + m_lock.unlock(m_active); + getLogger().debug( "JdbcConnection '" + m_dburl + "' has been returned to the pool." ); } public void run() { - while( m_monitoring ) + m_lock.lock(m_ready); + while( m_ready.size() < m_max ) { - synchronized( this ) - { - if( m_ready.size() < m_min ) - { - getLogger().debug( "Padding from " + m_ready.size() + " to " + - Math.min(m_min, (m_ready.size() + (m_max - m_currentCount))) + - " connections: " + m_dburl ); - - while( ( m_ready.size() < m_min ) && ( m_currentCount < m_max ) ) - { - try - { - m_ready.add( createJdbcConnection() ); - notify(); - } - - catch (SQLException se) - { - getLogger().error( "Could not create connection to database", se ); - } - } - } - else - { - if (m_ready.size() != m_min) { - getLogger().debug("Trimming from " + m_ready.size() + " to " + - m_min + " connections: " + m_dburl); - - while( m_ready.size() > m_min ) - { - recycle( (Recyclable)m_ready.remove( 0 ) ); - } - } - } - } - - try - { - Thread.sleep( 5 * 60 * 1000 ); - } - catch( final InterruptedException ie ) - { - getLogger().warn( "Caught an InterruptedException", ie ); + try { + m_ready.add( createJdbcConnection() ); + } catch (SQLException se) { + getLogger().error( "Could not create connection to database", se ); } } + + m_initialized = true; + m_lock.unlock(m_ready); } public void dispose() { - m_monitoring = false; + m_disposed = true; + + m_lock.lock(m_ready); - synchronized (m_ready) + while( ! m_ready.isEmpty() ) { - while( !m_ready.isEmpty() ) - { - recycle( (Recyclable)m_ready.remove( 0 ) ); - } + recycle( (Recyclable)m_ready.remove( 0 ) ); } + + m_lock.unlock(m_ready); } } 1.4 +2 -3 jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcDataSource.java Index: JdbcDataSource.java =================================================================== RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcDataSource.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- JdbcDataSource.java 2001/03/12 16:58:37 1.3 +++ JdbcDataSource.java 2001/03/16 15:14:09 1.4 @@ -20,7 +20,7 @@ * <code>java.sql.DriverManager</code>. * * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/03/12 16:58:37 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/03/16 15:14:09 $ */ public class JdbcDataSource extends AbstractLoggable @@ -48,11 +48,10 @@ final String passwd = configuration.getChild( "password" ).getValue( null ); final Configuration controler = configuration.getChild( "pool-controller" ); - final int min = controler.getAttributeAsInt( "min", 0 ); final int max = controler.getAttributeAsInt( "max", 3 ); final boolean autoCommit = configuration.getChild("auto-commit").getValueAsBoolean(true); - m_pool = new JdbcConnectionPool( dburl, user, passwd, min, max, autoCommit ); + m_pool = new JdbcConnectionPool( dburl, user, passwd, max, autoCommit ); m_pool.setLogger(getLogger()); m_pool.init(); } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]