noel        2004/04/16 07:49:48

  Modified:    src/java/org/apache/james/util/mordred Tag: branch_2_1_fcs
                        JdbcDataSource.java
  Log:
  Attempt to fix JAMES-254.  Change to ArrayList from Vector, and simplify 
synchronization.  This version has been tested with JDK 1.4.2 and works, but still 
fails with 1.4.1.  All threads that call getConnection block on the synchronized(pool) 
statement, even though no thread owns it.  Dain Sundstrom reports that this was a 
known problem with Hotspot (possibly just server) 1.4.0 and 1.4.1.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.18.4.8  +123 -124  
james-server/src/java/org/apache/james/util/mordred/JdbcDataSource.java
  
  Index: JdbcDataSource.java
  ===================================================================
  RCS file: 
/home/cvs/james-server/src/java/org/apache/james/util/mordred/JdbcDataSource.java,v
  retrieving revision 1.18.4.7
  retrieving revision 1.18.4.8
  diff -u -r1.18.4.7 -r1.18.4.8
  --- JdbcDataSource.java       14 Apr 2004 18:10:49 -0000      1.18.4.7
  +++ JdbcDataSource.java       16 Apr 2004 14:49:48 -0000      1.18.4.8
  @@ -23,7 +23,7 @@
   import java.sql.Connection;
   import java.sql.SQLException;
   
  -import java.util.Vector;
  +import java.util.ArrayList;
   
   import org.apache.avalon.excalibur.datasource.DataSourceComponent;
   import org.apache.avalon.framework.activity.Disposable;
  @@ -92,7 +92,7 @@
       // Maximum number of connections to have open at any point
       private int maxConn                             = 0;
       // collection of connection objects
  -    private Vector pool;
  +    private ArrayList pool;
       // Thread that checks for dead/aged connections and removes them from pool
       private Thread reaper;
       // Flag to indicate whether reaper thread should run
  @@ -129,7 +129,7 @@
           for(int attempts = 1; attempts <= 100; attempts++) {
               synchronized(pool) {
                   for(int i = 0; i < pool.size(); i++) {
  -                    PoolConnEntry entry = (PoolConnEntry)pool.elementAt(i);
  +                    PoolConnEntry entry = (PoolConnEntry)pool.get(i);
                       //Set the appropriate flags to make this connection
                       //marked as in use
                       try {
  @@ -153,58 +153,58 @@
                       }
                       //we were unable to get a lock on this entry.. so continue 
through list
                   } //loop through existing connections
  -            }
  -            //If we have 0, create another
  -            if(DEEP_DEBUG) {
  -                System.out.println(pool.size());
  -            }
  -            try {
  -                if(pool.size() == 0) {
  -                    //create a connection
  -                    PoolConnEntry entry = createConn();
  -                    if(entry != null) {
  -                        if(DEEP_DEBUG) {
  -                            StringBuffer deepDebugBuffer =
  -                                new StringBuffer(128)
  -                                        .append((new java.util.Date()).toString())
  -                                        .append(" returning new connection (")
  -                                        .append(count)
  -                                        .append(")");
  -                            System.out.println(deepDebugBuffer.toString());
  -                        }
  -                        return entry;
  -                    }
  -                    //looks like a connection was already created
  -                } else {
  -                    //Since we didn't find one, and we have < max connections, then 
consider whether
  -                    //  we create another
  -                    //if we've hit the 3rd attempt without getting a connection,
  -                    //  let's create another to anticipate a slow down
  -                    if((attempts == 2) && (pool.size() < maxConn || maxConn == 0)) {
  +                //If we have 0, create another
  +                if(DEEP_DEBUG) {
  +                    System.out.println(pool.size());
  +                }
  +                try {
  +                    if(pool.size() == 0) {
  +                        //create a connection
                           PoolConnEntry entry = createConn();
                           if(entry != null) {
                               if(DEEP_DEBUG) {
                                   StringBuffer deepDebugBuffer =
  -                                    new StringBuffer(32)
  +                                    new StringBuffer(128)
  +                                            .append((new 
java.util.Date()).toString())
                                               .append(" returning new connection (")
                                               .append(count)
                                               .append(")");
                                   System.out.println(deepDebugBuffer.toString());
                               }
                               return entry;
  -                        } else {
  -                            attempts = 1;
  +                        }
  +                        //looks like a connection was already created
  +                    } else {
  +                        //Since we didn't find one, and we have < max connections, 
then consider whether
  +                        //  we create another
  +                        //if we've hit the 3rd attempt without getting a connection,
  +                        //  let's create another to anticipate a slow down
  +                        if((attempts == 2) && (pool.size() < maxConn || maxConn == 
0)) {
  +                            PoolConnEntry entry = createConn();
  +                            if(entry != null) {
  +                                if(DEEP_DEBUG) {
  +                                    StringBuffer deepDebugBuffer =
  +                                        new StringBuffer(32)
  +                                                .append(" returning new connection 
(")
  +                                                .append(count)
  +                                                .append(")");
  +                                    System.out.println(deepDebugBuffer.toString());
  +                                }
  +                                return entry;
  +                            } else {
  +                                attempts = 1;
  +                            }
                           }
                       }
  -                }
  -            } catch(SQLException sqle) {
  -                //Ignore... error creating the connection
  -                StringWriter sout = new StringWriter();
  -                PrintWriter pout  = new PrintWriter(sout, true);
  -                pout.println("Error creating connection: ");
  -                sqle.printStackTrace(pout);
  -                if (getLogger().isErrorEnabled()) {
  -                    getLogger().error(sout.toString());
  +                } catch(SQLException sqle) {
  +                    //Ignore... error creating the connection
  +                    StringWriter sout = new StringWriter();
  +                    PrintWriter pout  = new PrintWriter(sout, true);
  +                    pout.println("Error creating connection: ");
  +                    sqle.printStackTrace(pout);
  +                    if (getLogger().isErrorEnabled()) {
  +                        getLogger().error(sout.toString());
  +                    }
                   }
               }
               //otherwise sleep 50ms 10 times, then create a connection
  @@ -271,7 +271,7 @@
                   //We don't show the password
                   getLogger().debug("max connections = " + maxConn);
               }
  -            pool         = new Vector();
  +            pool         = new ArrayList();
               reaperActive = true;
               reaper       = new Thread(this);
               reaper.setDaemon(true);
  @@ -389,61 +389,62 @@
       public void run() {
           try {
               while(reaperActive) {
  -                synchronized(pool) { for(int i = 0; i < pool.size(); i++) try {
  -                    PoolConnEntry entry = (PoolConnEntry)pool.elementAt(i);
  -                    long age            = System.currentTimeMillis() - 
entry.getLastActivity();
  -                    synchronized(entry) {
  -                        if((entry.getStatus() == PoolConnEntry.ACTIVE) &&
  -                           (age > ACTIVE_CONN_HARD_TIME_LIMIT)) {
  -                            StringBuffer logBuffer =
  -                                new StringBuffer(128)
  -                                        .append(" ***** connection ")
  -                                        .append(entry.getId())
  -                                        .append(" is way too old: ")
  -                                        .append(age)
  -                                        .append(" > ")
  -                                        .append(ACTIVE_CONN_HARD_TIME_LIMIT)
  -                                        .append(" and will be closed.");
  -                            getLogger().info(logBuffer.toString());
  -                            // This connection is way too old...
  -                            // kill it no matter what
  -                            finalizeEntry(entry);
  -                            continue;
  -                        }
  -                        if((entry.getStatus() == PoolConnEntry.ACTIVE) &&
  -                           (age > ACTIVE_CONN_TIME_LIMIT)) {
  -                            StringBuffer logBuffer =
  -                                new StringBuffer(128)
  -                                        .append(" ***** connection ")
  -                                        .append(entry.getId())
  -                                        .append(" is way too old: ")
  -                                        .append(age)
  -                                        .append(" > ")
  -                                        .append(ACTIVE_CONN_TIME_LIMIT);
  -                            getLogger().info(logBuffer.toString());
  -                            // This connection is way too old...
  -                            // just log it for now.
  -                            continue;
  -                        }
  -                        if((entry.getStatus() == PoolConnEntry.AVAILABLE) &&
  -                           (age > CONN_IDLE_LIMIT)) {
  -                            //We've got a connection that's too old... kill it
  -                            finalizeEntry(entry);
  -                            continue;
  +                synchronized(pool) {
  +                    for(int i = 0; i < pool.size(); i++) try {
  +                        PoolConnEntry entry = (PoolConnEntry)pool.get(i);
  +                        long age            = System.currentTimeMillis() - 
entry.getLastActivity();
  +                        synchronized(entry) {
  +                            if((entry.getStatus() == PoolConnEntry.ACTIVE) &&
  +                               (age > ACTIVE_CONN_HARD_TIME_LIMIT)) {
  +                                StringBuffer logBuffer =
  +                                    new StringBuffer(128)
  +                                            .append(" ***** connection ")
  +                                            .append(entry.getId())
  +                                            .append(" is way too old: ")
  +                                            .append(age)
  +                                            .append(" > ")
  +                                            .append(ACTIVE_CONN_HARD_TIME_LIMIT)
  +                                            .append(" and will be closed.");
  +                                getLogger().info(logBuffer.toString());
  +                                // This connection is way too old...
  +                                // kill it no matter what
  +                                finalizeEntry(entry);
  +                                continue;
  +                            }
  +                            if((entry.getStatus() == PoolConnEntry.ACTIVE) &&
  +                               (age > ACTIVE_CONN_TIME_LIMIT)) {
  +                                StringBuffer logBuffer =
  +                                    new StringBuffer(128)
  +                                            .append(" ***** connection ")
  +                                            .append(entry.getId())
  +                                            .append(" is way too old: ")
  +                                            .append(age)
  +                                            .append(" > ")
  +                                            .append(ACTIVE_CONN_TIME_LIMIT);
  +                                getLogger().info(logBuffer.toString());
  +                                // This connection is way too old...
  +                                // just log it for now.
  +                                continue;
  +                            }
  +                            if((entry.getStatus() == PoolConnEntry.AVAILABLE) &&
  +                               (age > CONN_IDLE_LIMIT)) {
  +                                //We've got a connection that's too old... kill it
  +                                finalizeEntry(entry);
  +                                continue;
  +                            }
                           }
                       }
  -                }
  -                catch (Throwable ex)
  -                {
  -                    StringWriter sout = new StringWriter();
  -                    PrintWriter pout = new PrintWriter(sout, true);
  -                    pout.println("Reaper Error: ");
  -                    ex.printStackTrace(pout);
  -                    if (getLogger().isErrorEnabled()) {
  -                        getLogger().error(sout.toString());
  +                    catch (Throwable ex)
  +                    {
  +                        StringWriter sout = new StringWriter();
  +                        PrintWriter pout = new PrintWriter(sout, true);
  +                        pout.println("Reaper Error: ");
  +                        ex.printStackTrace(pout);
  +                        if (getLogger().isErrorEnabled()) {
  +                            getLogger().error(sout.toString());
  +                        }
                       }
                   }
  -                }
                   try {
                       // Check for activity every 5 seconds
                       Thread.sleep(5000L);
  @@ -509,33 +510,31 @@
                   }
                   return null;
               }
  -        }
  -        try {
  -            entry = new PoolConnEntry(this,
  -                                      java.sql.DriverManager.getConnection(jdbcURL, 
jdbcUsername,
  -                                                                           
jdbcPassword),
  -                                      ++connectionCount);
  -            if (getLogger().isDebugEnabled())
  -            {
  -                getLogger().debug("Opening connection " + entry);
  -            }
  -            entry.lock();
  -            pool.addElement(entry);
  -            return entry;
  -        } catch(SQLException sqle) {
  -            //Shouldn't ever happen, but it did, just return null.
  -            // Exception from DriverManager.getConnection() - log it, and return 
null
  -            StringWriter sout = new StringWriter();
  -            PrintWriter pout = new PrintWriter(sout, true);
  -            pout.println("Error creating connection: ");
  -            sqle.printStackTrace(pout);
  -            if (getLogger().isErrorEnabled()) {
  -                getLogger().error(sout.toString());
  -            }
  -            return null;
  -        } finally {
  -            synchronized(pool) {
  -                connCreationsInProgress--;
  +            try {
  +                entry = new PoolConnEntry(this,
  +                                          
java.sql.DriverManager.getConnection(jdbcURL, jdbcUsername,
  +                                                                               
jdbcPassword),
  +                                          ++connectionCount);
  +                if (getLogger().isDebugEnabled())
  +                {
  +                    getLogger().debug("Opening connection " + entry);
  +                }
  +                entry.lock();
  +                pool.add(entry);
  +                return entry;
  +            } catch(SQLException sqle) {
  +                //Shouldn't ever happen, but it did, just return null.
  +                // Exception from DriverManager.getConnection() - log it, and 
return null
  +                StringWriter sout = new StringWriter();
  +                PrintWriter pout = new PrintWriter(sout, true);
  +                pout.println("Error creating connection: ");
  +                sqle.printStackTrace(pout);
  +                if (getLogger().isErrorEnabled()) {
  +                    getLogger().error(sout.toString());
  +                }
  +                return null;
  +            } finally {
  +                    connCreationsInProgress--;
               }
           }
       }
  @@ -551,7 +550,7 @@
                   entry.finalize();
               } catch(Exception fe) {
               }
  -            pool.removeElement(entry);
  +            pool.remove(entry);
           }
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to