User: d_jencks
  Date: 01/08/01 12:29:37

  Modified:    src/main/org/jboss/pool/connector BaseConnectionManager.java
  Log:
  Fixed race condition in listeners, bug 446915
  
  Revision  Changes    Path
  1.2       +37 -22    
jbosspool/src/main/org/jboss/pool/connector/BaseConnectionManager.java
  
  Index: BaseConnectionManager.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jbosspool/src/main/org/jboss/pool/connector/BaseConnectionManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BaseConnectionManager.java        2001/05/15 07:58:24     1.1
  +++ BaseConnectionManager.java        2001/08/01 19:29:37     1.2
  @@ -28,6 +28,7 @@
    * handles connection pools, and provides listener implementations
    * for LocalTransactions, XAResources, and no transactions.
    * @author Aaron Mulder [EMAIL PROTECTED]
  + * @author David Jencks [EMAIL PROTECTED]
    */
   public abstract class BaseConnectionManager implements ConnectionManager {
       public final static String POOL_CONFIGURATION_KEY="PoolConfiguration";
  @@ -166,6 +167,7 @@
           protected ObjectPool pool;
           protected ManagedConnection con;
   
  +
           protected ConnectionListener(ObjectPool pool, ManagedConnection con) {
               this.pool = pool;
               this.con = con;
  @@ -314,6 +316,9 @@
        * error occurs.  The connection is not returned immediately on
        * close because some connections using LocalTransaction may not
        * be able to maintain separate state for separate transactions.
  +     *
  +     * This implementation uses Synchronization.afterCompletion 
  +     * to commit the local transaction, since there is no XAResource.  
        */
       protected class SharedLocalConnectionListener extends ConnectionListener 
implements Synchronization, ConnectionEventListener {
           private Transaction trans;
  @@ -383,23 +388,14 @@
               }
   
               if(getHandleCount() <= 0) {
  -                if(pool != null) {
  -                    pool.releaseObject(con);
  -                } else {
  -                    try {
  -                        con.destroy();
  -                    } catch(ResourceException e) {
  -                        e.printStackTrace();
  -                    }
  -                }
  -                clear();
  +                done(pool, con);   // Clean up and return to pool or destroy.
               } else {
                   trans = null;
                   local = null;
               }
           }
   
  -        public void beforeCompletion() {
  +        public void beforeCompletion() { 
           }
   
           /**
  @@ -407,6 +403,9 @@
            * the connection is destroyed and this listener is cleared.
            */
           public void connectionErrorOccurred(ConnectionEvent evt) {
  +           System.out.println("===========================================");
  +           System.out.println("Connection Error Occurred");
  +           System.out.println("===========================================");
               try {
                   local.rollback();
               } catch(Exception e) {}
  @@ -416,6 +415,8 @@
               clear();
           }
   
  +
  +
           /**
            * Only return connection to the pool if this is the last handle to
            * the current ManagedConnection, and there's no TX.  This could
  @@ -426,16 +427,7 @@
               connectionHandleClosed(evt.getConnectionHandle());
               if(removeHandle() <= 0) {  // If this was the last handle...
                   if(trans == null) {    // And the transaction is over...
  -                    if(pool != null) { // Put back in the pool...
  -                        pool.releaseObject(con);
  -                    } else {
  -                        try {          // Or get rid of entirely.
  -                            con.destroy();
  -                        } catch(ResourceException e) {
  -                            e.printStackTrace();
  -                        }
  -                    }
  -                    clear();
  +                    done(pool, con);   // Clean up and return to pool or destroy.
                   }
               }
           }
  @@ -464,6 +456,26 @@
               trans = null;
               local = null;
           }
  +
  +        private void done(ObjectPool pool, ManagedConnection con) {
  +            //Clear the ConnectionListener _before_ returning to the pool
  +            //to avoid a race in which the connection is reused before the
  +            //connection listener is cleared,
  +            // and this method calls con.destroy() on null.
  +            clear();
  +            //clear cleared the pool and con instance variables, which is why we 
  +            //passed them in.
  +            if(pool != null) {
  +                pool.releaseObject(con);
  +            } else {
  +                try {
  +                    con.destroy();
  +                } catch(ResourceException e) {
  +                    e.printStackTrace();
  +                }
  +            }
  +        }
  +
       }
   
       /**
  @@ -578,8 +590,11 @@
   
               // Clean up if pooled or if transaction is over
               if(pool != null) {
  -                pool.releaseObject(con);
  +                //Avoid race condition whereby con can be reused before clear is 
called.
  +                ObjectPool mypool = pool;
  +                ManagedConnection mycon = con;
                   clear();
  +                mypool.releaseObject(mycon);
               } else if (trans == null) {
                   try {
                       con.destroy();
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to