jtaylor     02/05/17 07:12:53

  Modified:    src/java/org/apache/jcs/access CacheAccess.java
               src/java/org/apache/jcs/auxiliary/lateral
                        LateralCacheManager.java
                        LateralCacheNoWaitFacade.java
                        LateralCacheRestore.java
               src/java/org/apache/jcs/auxiliary/lateral/socket/tcp
                        LateralCacheTCPListener.java LateralTCPSender.java
               src/java/org/apache/jcs/auxiliary/remote
                        RemoteCacheListener.java
               src/java/org/apache/jcs/auxiliary/remote/group
                        RemoteGroupCacheListener.java
               src/java/org/apache/jcs/auxiliary/remote/server
                        RemoteCacheServer.java
                        RemoteCacheServerListener.java
               src/java/org/apache/jcs/engine CacheConstants.java
                        CacheEventQueue.java
               src/java/org/apache/jcs/engine/behavior ICompositeCache.java
               src/java/org/apache/jcs/engine/control Cache.java
                        CacheHub.java
               src/java/org/apache/jcs/engine/control/group GroupCache.java
               src/java/org/apache/jcs/utils/locking
                        ReadWriteLockManager.java RwLockHolder.java
               src/test/org/apache/jcs/auxiliary/lateral/http/broadcast
                        LateralCacheTester.java
  Added:       .        project.properties
  Removed:     src/java/org/apache/jcs/auxiliary/lateral/http/broadcast
                        LateralCacheMulticaster.java
                        LateralCacheThread.java LateralCacheUnicaster.java
               src/java/org/apache/jcs/auxiliary/lateral/http/remove
                        DeleteLateralCacheMulticaster.java
                        DeleteLateralCacheUnicaster.java
               src/java/org/apache/jcs/auxiliary/lateral/http/server
                        AbstractDeleteCacheServlet.java
                        DeleteCacheServlet.java
                        LateralCacheServletReciever.java
               src/java/org/apache/jcs/auxiliary/lateral/javagroups
                        JGConnectionHolder.java LateralCacheJGListener.java
                        LateralGroupCacheJGListener.java
                        LateralJGReceiver.java
                        LateralJGReceiverConnection.java
                        LateralJGSender.java LateralJGService.java
               src/java/org/apache/jcs/auxiliary/lateral/javagroups/behavior
                        IJGConstants.java ILateralCacheJGAttributes.java
                        ILateralCacheJGListener.java
               src/java/org/apache/jcs/auxiliary/lateral/javagroups/utils
                        JGRpcOpener.java JGSocketOpener.java
               src/java/org/apache/jcs/auxiliary/lateral/socket/tcp
                        LateralGroupCacheTCPListener.java
                        LateralTCPReceiver.java
                        LateralTCPReceiverConnection.java
               src/java/org/apache/jcs/auxiliary/lateral/socket/udp
                        LateralCacheUDPListener.java
                        LateralGroupCacheUDPListener.java
                        LateralUDPReceiver.java LateralUDPSender.java
                        LateralUDPService.java
               src/java/org/apache/jcs/auxiliary/lateral/xmlrpc
                        LateralCacheXMLRPCListener.java
                        LateralGroupCacheXMLRPCListener.java
                        LateralXMLRPCReceiver.java
                        LateralXMLRPCReceiverConnection.java
                        LateralXMLRPCSender.java LateralXMLRPCService.java
               src/java/org/apache/jcs/auxiliary/lateral/xmlrpc/behavior
                        ILateralCacheXMLRPCListener.java
                        IXMLRPCConstants.java
               src/java/org/apache/jcs/auxiliary/lateral/xmlrpc/utils
                        XMLRPCSocketOpener.java
  Log:
  A couple of things:
  
      - Cleaning up and simplifying the TCP lateral listener. It now uses a
        thread pool. Just getting started there.
  
      - Got rid of EXCLUDE_REMOTE_CACHE, INCLUDE_REMOTE_CACHE, methods in
        ICompositeCache that accept bools. Replaced with local{Update|Get|
        Remove|RemoveAll}
  
      - Pushed 'put' methods out of composite cache, everything to create a
        CacheElement is noe handled in CacheAccess (rather than being split
        up).
  
  Revision  Changes    Path
  1.1                  jakarta-turbine-jcs/project.properties
  
  Index: project.properties
  ===================================================================
  maven.test.callback.pre-test.buildFile = build.xml
  maven.test.callback.pre-test.buildTarget = jcs:test-prepare
  
  
  
  1.6       +44 -22    
jakarta-turbine-jcs/src/java/org/apache/jcs/access/CacheAccess.java
  
  Index: CacheAccess.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/access/CacheAccess.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- CacheAccess.java  14 May 2002 17:55:36 -0000      1.5
  +++ CacheAccess.java  17 May 2002 14:12:51 -0000      1.6
  @@ -82,7 +82,7 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Aaron Smuts</a>
    * @created February 13, 2002
  - * @version $Id: CacheAccess.java,v 1.5 2002/05/14 17:55:36 asmuts Exp $
  + * @version $Id: CacheAccess.java,v 1.6 2002/05/17 14:12:51 jtaylor Exp $
    */
   public class CacheAccess implements ICacheAccess
   {
  @@ -274,33 +274,41 @@
       public void put( Object name, Object obj )
           throws CacheException
       {
  -        try
  -        {
  -            cacheControl.put( ( Serializable ) name, ( Serializable ) obj );
  -        }
  -        catch ( Exception e )
  -        {
  -            throw new CacheException( e );
  -        }
  +        // Call put with the contained caches default attributes.
  +
  +        put( ( Serializable ) name,
  +             ( Serializable ) obj,
  +             cacheControl.getElementAttributes() );
       }
   
       /**
        * Place a new object in the cache. This form allows attributes to associate
        * with the object may be specified with attr.
  -     *
  -     * @param name Key object will be stored with
  -     * @param obj Object to store
  -     * @param attr Attributes to store object with
  -     * @exception CacheException
        */
  -    public void put( Object name, Object obj, IElementAttributes attr )
  +    public void put( Object key, Object val, IElementAttributes attr )
           throws CacheException
       {
  +        if ( key == null  )
  +        {
  +            throw new CacheException( "Key must not be null" );
  +        }
  +        else if ( val == null )
  +        {
  +            throw new CacheException( "Value must not be null" );
  +        }
  +
  +        // Create the element and update. This may throw an IOException which
  +        // should be wrapped by cache access.
  +
           try
           {
  -            cacheControl.put( ( Serializable ) name,
  -                              ( Serializable ) obj,
  -                              attr );
  +            CacheElement ce = new CacheElement( cacheControl.getCacheName(),
  +                              (Serializable) key,
  +                              (Serializable) val );
  +
  +            ce.setElementAttributes( attr );
  +
  +            cacheControl.update( ce );
           }
           catch ( Exception e )
           {
  @@ -319,14 +327,28 @@
       public void destroy()
           throws CacheException
       {
  -        cacheControl.removeAll();
  +        try
  +        {
  +            cacheControl.removeAll();
  +        }
  +        catch( IOException e )
  +        {
  +            throw new CacheException( e );
  +        }
       }
   
       /** Description of the Method */
       public void remove()
           throws CacheException
       {
  -        cacheControl.removeAll();
  +        try
  +        {
  +            cacheControl.removeAll();
  +        }
  +        catch( IOException e )
  +        {
  +            throw new CacheException( e );
  +        }
       }
   
       /**
  @@ -486,10 +508,10 @@
   
       // protected void dumpMap()
       // {
  -    //     cache_control.dumpMap();
  +    //     cacheControl.dumpMap();
       // }
       // protected void dumpCacheEntries()
       // {
  -    //     cache_control.dumpCacheEntries();
  +    //     cacheControl.dumpCacheEntries();
       // }
   }
  
  
  
  1.4       +4 -52     
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheManager.java
  
  Index: LateralCacheManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LateralCacheManager.java  10 Apr 2002 15:01:00 -0000      1.3
  +++ LateralCacheManager.java  17 May 2002 14:12:52 -0000      1.4
  @@ -13,15 +13,8 @@
   import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheListener;
   import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheObserver;
   import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheService;
  -import org.apache.jcs.auxiliary.lateral.javagroups.LateralGroupCacheJGListener;
  -import org.apache.jcs.auxiliary.lateral.javagroups.LateralJGService;
  -import org.apache.jcs.auxiliary.lateral.socket.tcp.LateralGroupCacheTCPListener;
   import org.apache.jcs.auxiliary.lateral.socket.tcp.LateralTCPService;
  -import org.apache.jcs.auxiliary.lateral.socket.udp.LateralGroupCacheUDPListener;
  -import org.apache.jcs.auxiliary.lateral.socket.udp.LateralUDPService;
  -import org.apache.jcs.auxiliary.lateral.xmlrpc.LateralGroupCacheXMLRPCListener;
  -import org.apache.jcs.auxiliary.lateral.xmlrpc.LateralXMLRPCService;
  -import org.apache.jcs.engine.behavior.ICache;
  +import org.apache.jcs.auxiliary.lateral.socket.tcp.LateralCacheTCPListener;
   
   /**
    * Creates lateral caches. Lateral caches are primarily used for removing non
  @@ -120,40 +113,12 @@
   
           try
           {
  -            if ( lca.getTransmissionType() == lca.UDP )
  -            {
  -                // need to allow for this to be a service.
  -                // should wrap sender and new kind of receiver?
  -
  -                log.debug( "Creating UDP service" );
  -
  -                this.lateralService = new LateralUDPService( lca );
  -            }
  -            else if ( lca.getTransmissionType() == lca.HTTP )
  -            {
  -                log.debug( "[NOT] Creating HTTP service" );
  -
  -                // FIXME: Why is this disabled?
  -                //this.lateralService = new LateralHTTPService( lca );
  -            }
  -            else if ( lca.getTransmissionType() == lca.TCP )
  +            if ( lca.getTransmissionType() == lca.TCP )
               {
                   log.debug( "Creating TCP service" );
   
                   this.lateralService = new LateralTCPService( lca );
               }
  -            else if ( lca.getTransmissionType() == lca.XMLRPC )
  -            {
  -                log.debug( "Creating XMLRPC service" );
  -
  -                this.lateralService = new LateralXMLRPCService( lca );
  -            }
  -            else if ( lca.getTransmissionType() == lca.JAVAGROUPS )
  -            {
  -                log.debug( "Creating JAVAGROUPS service" );
  -
  -                this.lateralService = new LateralJGService( lca );
  -            }
               else
               {
                   log.error( "Type not recognized, must zombie" );
  @@ -232,22 +197,9 @@
   
           try
           {
  -            // need to set listener based on transmissionType
  -            if ( lca.getTransmissionType() == lca.UDP )
  -            {
  -                addLateralCacheListener( cacheName, 
LateralGroupCacheUDPListener.getInstance( lca ) );
  -            }
  -            else if ( lca.getTransmissionType() == lca.TCP )
  -            {
  -                addLateralCacheListener( cacheName, 
LateralGroupCacheTCPListener.getInstance( lca ) );
  -            }
  -            else if ( lca.getTransmissionType() == lca.XMLRPC )
  -            {
  -                addLateralCacheListener( cacheName, 
LateralGroupCacheXMLRPCListener.getInstance( lca ) );
  -            }
  -            else if ( lca.getTransmissionType() == lca.JAVAGROUPS )
  +            if ( lca.getTransmissionType() == lca.TCP )
               {
  -                addLateralCacheListener( cacheName, 
LateralGroupCacheJGListener.getInstance( lca ) );
  +                addLateralCacheListener( cacheName, 
LateralCacheTCPListener.getInstance( lca ) );
               }
           }
           catch ( IOException ioe )
  
  
  
  1.3       +1 -4      
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
  
  Index: LateralCacheNoWaitFacade.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LateralCacheNoWaitFacade.java     10 Apr 2002 15:01:00 -0000      1.2
  +++ LateralCacheNoWaitFacade.java     17 May 2002 14:12:52 -0000      1.3
  @@ -70,10 +70,7 @@
               try
               {
                   Object obj = noWaits[ i ].get( key );
  -                if ( log.isDebugEnabled() )
  -                {
  -                    log.debug( "obj = " + obj );
  -                }
  +
                   if ( obj != null )
                   {
                       // return after first success
  
  
  
  1.2       +1 -29     
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheRestore.java
  
  Index: LateralCacheRestore.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheRestore.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LateralCacheRestore.java  7 Apr 2002 16:55:23 -0000       1.1
  +++ LateralCacheRestore.java  17 May 2002 14:12:52 -0000      1.2
  @@ -5,12 +5,6 @@
   
   import org.apache.jcs.auxiliary.lateral.socket.tcp.LateralTCPService;
   
  -import org.apache.jcs.auxiliary.lateral.socket.udp.LateralUDPService;
  -
  -import org.apache.jcs.auxiliary.lateral.javagroups.LateralJGService;
  -
  -import org.apache.jcs.auxiliary.lateral.xmlrpc.LateralXMLRPCService;
  -
   import org.apache.jcs.engine.behavior.ICacheRestore;
   
   import org.apache.commons.logging.Log;
  @@ -58,31 +52,9 @@
   
           try
           {
  -
  -            // restore based on type.  Only the tcp scoket type really needs 
restoring.
  -            if ( lcm.lca.getTransmissionType() == lcm.lca.UDP )
  -            {
  -                lateralObj = new LateralUDPService( lcm.lca );
  -            }
  -            else
  -                if ( lcm.lca.getTransmissionType() == lcm.lca.JAVAGROUPS )
  -            {
  -                lateralObj = new LateralJGService( lcm.lca );
  -            }
  -            else
  -                if ( lcm.lca.getTransmissionType() == lcm.lca.XMLRPC )
  -            {
  -                lateralObj = new LateralXMLRPCService( lcm.lca );
  -            }
  -            else
  -                if ( lcm.lca.getTransmissionType() == lcm.lca.TCP )
  +            if ( lcm.lca.getTransmissionType() == lcm.lca.TCP )
               {
                   lateralObj = new LateralTCPService( lcm.lca );
  -            }
  -            else
  -                if ( lcm.lca.getTransmissionType() == lcm.lca.HTTP )
  -            {
  -
               }
           }
           catch ( Exception ex )
  
  
  
  1.5       +253 -101  
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralCacheTCPListener.java
  
  Index: LateralCacheTCPListener.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralCacheTCPListener.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- LateralCacheTCPListener.java      10 Apr 2002 15:01:00 -0000      1.4
  +++ LateralCacheTCPListener.java      17 May 2002 14:12:52 -0000      1.5
  @@ -53,50 +53,90 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    */
  +
   import java.io.IOException;
  +import java.io.ObjectInputStream;
  +import java.io.ObjectOutputStream;
   import java.io.Serializable;
  -
  +import java.net.InetAddress;
  +import java.net.ServerSocket;
  +import java.net.Socket;
   import java.util.HashMap;
   
  +import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.jcs.auxiliary.lateral.LateralCacheInfo;
  -
  +import org.apache.jcs.auxiliary.lateral.LateralElementDescriptor;
   import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheAttributes;
   import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheListener;
  -import 
org.apache.jcs.auxiliary.lateral.socket.tcp.behavior.ILateralCacheTCPListener;
  -
  -import org.apache.jcs.engine.behavior.ICache;
  +import org.apache.jcs.engine.CacheConstants;
   import org.apache.jcs.engine.behavior.ICacheElement;
   import org.apache.jcs.engine.behavior.ICompositeCache;
  -
   import org.apache.jcs.engine.control.CacheHub;
  -import org.apache.jcs.engine.CacheConstants;
  -
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
   
   /**
  - * Description of the Class
  + * Listens for connections from other TCP lateral caches and handles them.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Aaron Smuts</a>
  - * @created January 15, 2002
  - * @version $Id: LateralCacheTCPListener.java,v 1.8 2002/02/15 04:33:37 jtaylor
  - *      Exp $
  + * @version $Id: LateralCacheTCPListener.java,v 1.5 2002/05/17 14:12:52 jtaylor Exp 
$
    */
  -public class LateralCacheTCPListener implements ILateralCacheTCPListener, 
Serializable
  +public class LateralCacheTCPListener
  +    implements ILateralCacheListener, Serializable
   {
       private final static Log log =
           LogFactory.getLog( LateralCacheTCPListener.class );
   
  -    /** Description of the Field */
  +    /** How long the server will block on an accept(). 0 is infinte. */
  +    private final static int acceptTimeOut = 0;
  +
  +    /** The CacheHub this listener is associated with */
       protected static transient CacheHub cacheMgr;
  -    /** Description of the Field */
  +
  +    /** Map of available instances, keyed by port */
       protected final static HashMap instances = new HashMap();
   
  -    // instance vars
  -    private LateralTCPReceiver receiver;
  +    // ---------- instance variables
  +
  +    /** The socket listener */
  +    private ListenerThread receiver;
  +
       private ILateralCacheAttributes ilca;
  -    private boolean inited = false;
  +    private int port;
  +
  +    private PooledExecutor pooledExecutor = new PooledExecutor();
   
  +    // -------------------------------------------------------- factory methods
  +
  +    /**
  +     * Gets the instance attribute of the LateralCacheTCPListener class
  +     *
  +     * @return The instance value
  +     */
  +    public synchronized static ILateralCacheListener
  +        getInstance( ILateralCacheAttributes ilca )
  +    {
  +        ILateralCacheListener ins = ( ILateralCacheListener )
  +            instances.get( String.valueOf( ilca.getTcpListenerPort() ) );
  +
  +        if ( ins == null )
  +        {
  +            ins = new LateralCacheTCPListener( ilca );
  +
  +            ins.init();
  +
  +            instances.put( String.valueOf( ilca.getTcpListenerPort() ), ins );
  +
  +            if ( log.isDebugEnabled() )
  +            {
  +                log.debug( "created new listener " + ilca.getTcpListenerPort() );
  +            }
  +        }
  +
  +        return ins;
  +    }
  +
  +    // ------------------------------------------------------- instance methods
   
       /**
        * Only need one since it does work for all regions, just reference by
  @@ -109,28 +149,25 @@
           this.ilca = ilca;
       }
   
  -
       /** Description of the Method */
       public void init()
       {
           try
           {
  -            // need to connect based on type
  -            //ILateralCacheListener ilcl = this;
  -            //p( "in init, ilcl = " + ilcl );
  -            receiver = new LateralTCPReceiver( ilca, this );
  -            Thread t = new Thread( receiver );
  -            t.start();
  +            this.port = ilca.getTcpListenerPort();
  +
  +            receiver = new ListenerThread();
  +
  +            receiver.start();
           }
           catch ( Exception ex )
           {
               log.error( ex );
  +
               throw new IllegalStateException( ex.getMessage() );
           }
  -        inited = true;
       }
   
  -
       /**
        * let the lateral cache set a listener_id. Since there is only one
        * listerenr for all the regions and every region gets registered? the id
  @@ -149,7 +186,6 @@
           }
       }
   
  -
       /**
        * Gets the listenerId attribute of the LateralCacheTCPListener object
        *
  @@ -158,65 +194,30 @@
       public byte getListenerId()
           throws IOException
       {
  -
  -        // set the manager since we are in use
  -        //getCacheManager();
  -
  -        //p( "get listenerId" );
  -        if ( log.isDebugEnabled() )
  -        {
  -            log.debug( "get listenerId = " + LateralCacheInfo.listenerId );
  -        }
           return LateralCacheInfo.listenerId;
       }
   
  +    // ---------------------------------------- interface ILateralCacheListener
   
  -    /**
  -     * Gets the instance attribute of the LateralCacheTCPListener class
  -     *
  -     * @return The instance value
  -     */
  -    public static ILateralCacheListener getInstance( ILateralCacheAttributes ilca )
  -    {
  -        //throws IOException, NotBoundException
  -        ILateralCacheListener ins = ( ILateralCacheListener ) instances.get( 
String.valueOf( ilca.getTcpListenerPort() ) );
  -        if ( ins == null )
  -        {
  -            synchronized ( LateralCacheTCPListener.class )
  -            {
  -                if ( ins == null )
  -                {
  -                    ins = new LateralCacheTCPListener( ilca );
  -                    ins.init();
  -                }
  -                if ( log.isDebugEnabled() )
  -                {
  -                    log.debug( "created new listener " + ilca.getTcpListenerPort() 
);
  -                }
  -                instances.put( String.valueOf( ilca.getTcpListenerPort() ), ins );
  -            }
  -        }
  -        return ins;
  -    }
  -
  -
  -    //////////////////////////// implements the ILateralCacheListener interface. 
//////////////
  -    /** */
  -    public void handlePut( ICacheElement cb )
  +    public void handlePut( ICacheElement element )
           throws IOException
       {
           if ( log.isDebugEnabled() )
           {
  -            log.debug( "PUTTING ELEMENT FROM LATERAL" );
  +            log.debug( "handlePut> cacheName=" + element.getCacheName() + ", key=" 
+ element.getKey() );
           }
  -        getCacheManager();
  -        ICompositeCache cache = ( ICompositeCache ) cacheMgr.getCache( 
cb.getCacheName() );
  -        cache.update( cb, CacheConstants.REMOTE_INVOKATION );
  -        //handleRemove(cb.getCacheName(), cb.getKey());
  -    }
   
  +        // This was the following, however passing true in for updateRemotes
  +        // causes an a loop, since the element will the be sent to the sender.
  +        // Passing false in fixes things, but I'm not sure I understand all
  +        // the details yet.
  +        //
  +        // getCache( element.getCacheName() )
  +        //    .update( element, CacheConstants.REMOTE_INVOKATION );
  +
  +        getCache( element.getCacheName() ).localUpdate( element );
  +    }
   
  -    /** Description of the Method */
       public void handleRemove( String cacheName, Serializable key )
           throws IOException
       {
  @@ -225,15 +226,9 @@
               log.debug( "handleRemove> cacheName=" + cacheName + ", key=" + key );
           }
   
  -        getCacheManager();
  -        // interface limitation here
  -
  -        ICompositeCache cache = ( ICompositeCache ) cacheMgr.getCache( cacheName );
  -        cache.remove( key, CacheConstants.REMOTE_INVOKATION );
  +        getCache( cacheName ).localRemove( key );
       }
   
  -
  -    /** Description of the Method */
       public void handleRemoveAll( String cacheName )
           throws IOException
       {
  @@ -241,12 +236,10 @@
           {
               log.debug( "handleRemoveAll> cacheName=" + cacheName );
           }
  -        getCacheManager();
  -        ICache cache = cacheMgr.getCache( cacheName );
  -        cache.removeAll();
  +
  +        getCache( cacheName ).localRemoveAll();
       }
   
  -    /** Test get implementation. */
       public Serializable handleGet( String cacheName, Serializable key )
           throws IOException
       {
  @@ -254,13 +247,10 @@
           {
               log.debug( "handleGet> cacheName=" + cacheName + ", key = " + key );
           }
  -        getCacheManager();
  -        ICompositeCache cache = ( ICompositeCache ) cacheMgr.getCache( cacheName );
  -        // get container
  -        return cache.get( key, CacheConstants.REMOTE_INVOKATION );
  +
  +        return getCache( cacheName ).localGet( key );
       }
   
  -    /** Description of the Method */
       public void handleDispose( String cacheName )
           throws IOException
       {
  @@ -268,30 +258,192 @@
           {
               log.debug( "handleDispose> cacheName=" + cacheName );
           }
  +
           CacheHub cm = ( CacheHub ) cacheMgr;
  -        cm.freeCache( cacheName, CacheConstants.REMOTE_INVOKATION );
  +        cm.freeCache( cacheName, true );
       }
   
  -
  -    // override for new funcitonality
       /**
        * Gets the cacheManager attribute of the LateralCacheTCPListener object
        */
  -    protected void getCacheManager()
  +    protected ICompositeCache getCache( String name )
       {
           if ( cacheMgr == null )
           {
               cacheMgr = CacheHub.getInstance();
  +
               if ( log.isDebugEnabled() )
               {
                   log.debug( "cacheMgr = " + cacheMgr );
               }
           }
  -        else
  +
  +        return ( ICompositeCache ) cacheMgr.getCache( name );
  +    }
  +
  +    // ---------------------------------------------------------- inner classes
  +
  +    /**
  +     * Processes commands from the server socket. There should be one listener
  +     * for each configured TCP lateral.
  +     */
  +    public class ListenerThread extends Thread
  +    {
  +        /** Main processing method for the ListenerThread object */
  +        public void run()
           {
  -            if ( log.isDebugEnabled() )
  +            try
  +            {
  +                log.info( "Listening on port " + port );
  +
  +                ServerSocket serverSocket = new ServerSocket( port );
  +                serverSocket.setSoTimeout( acceptTimeOut );
  +
  +                ConnectionHandler handler;
  +
  +                while ( true )
  +                {
  +                    if ( log.isDebugEnabled() )
  +                    {
  +                        log.debug( "Waiting for clients to connect " );
  +                    }
  +
  +                    Socket socket = serverSocket.accept();
  +
  +                    if ( log.isDebugEnabled() )
  +                    {
  +                        InetAddress inetAddress = socket.getInetAddress();
  +
  +                        log.debug( "Connected to client at " + inetAddress );
  +                    }
  +
  +                    handler = new ConnectionHandler( socket );
  +
  +                    pooledExecutor.execute( handler );
  +                }
  +            }
  +            catch ( Exception e )
  +            {
  +                log.error( "Exception caught in TCP listener", e );
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Separate thread run when a command comes into the LateralTCPReceiver.
  +     */
  +    public class ConnectionHandler implements Runnable
  +    {
  +        private Socket socket;
  +
  +        /** Construct for a given socket */
  +        public ConnectionHandler( Socket socket )
  +        {
  +            this.socket = socket;
  +        }
  +
  +        /**
  +         * Main processing method for the LateralTCPReceiverConnection object
  +         */
  +        public void run()
  +        {
  +            ObjectInputStream ois;
  +
  +            try
               {
  -                log.debug( "already got cacheMgr = " + cacheMgr );
  +                ois = new ObjectInputStream( socket.getInputStream() );
  +                ;
  +            }
  +            catch ( Exception e )
  +            {
  +                log.error( "Could not open ObjectInputStream to " + socket, e );
  +
  +                return;
  +            }
  +
  +            LateralElementDescriptor led;
  +
  +            try
  +            {
  +                while ( true )
  +                {
  +                    led = ( LateralElementDescriptor ) ois.readObject();
  +
  +                    if ( led == null )
  +                    {
  +                        log.debug( "LateralElementDescriptor is null" );
  +                        continue;
  +                    }
  +                    if ( led.requesterId == LateralCacheInfo.listenerId )
  +                    {
  +                        log.debug( "from self" );
  +                    }
  +                    else
  +                    {
  +                        if ( log.isDebugEnabled() )
  +                        {
  +                            log.debug( "receiving LateralElementDescriptor from 
another"
  +                                       + "led = " + led
  +                                       + ", led.command = " + led.command
  +                                       + ", led.ce = " + led.ce );
  +                        }
  +
  +                        handle( led );
  +                    }
  +                }
  +            }
  +            catch ( java.io.EOFException e )
  +            {
  +                log.info( "Caught java.io.EOFException closing conneciton." );
  +            }
  +            catch ( java.net.SocketException e )
  +            {
  +                log.info( "Caught java.net.SocketException closing conneciton." );
  +            }
  +            catch ( Exception e )
  +            {
  +                log.error( "Unexpected exception. Closing conneciton", e );
  +            }
  +
  +            try
  +            {
  +                ois.close();
  +            }
  +            catch ( Exception e )
  +            {
  +                log.error( "Could not close connection", e );
  +            }
  +        }
  +
  +        private void handle( LateralElementDescriptor led ) throws IOException
  +        {
  +            String cacheName = led.ce.getCacheName();
  +            Serializable key = led.ce.getKey();
  +
  +            if ( led.command == LateralElementDescriptor.UPDATE )
  +            {
  +                handlePut( led.ce );
  +            }
  +            else if ( led.command == LateralElementDescriptor.REMOVE )
  +            {
  +                handleRemove( cacheName, key );
  +            }
  +            else if ( led.command == LateralElementDescriptor.REMOVEALL )
  +            {
  +                handleRemoveAll( cacheName );
  +            }
  +            else if ( led.command == LateralElementDescriptor.GET )
  +            {
  +                Serializable obj = handleGet( cacheName, key );
  +
  +                ObjectOutputStream oos =
  +                    new ObjectOutputStream( socket.getOutputStream() );
  +
  +                if ( oos != null )
  +                {
  +                    oos.writeObject( obj );
  +                    oos.flush();
  +                }
               }
           }
       }
  
  
  
  1.4       +1 -4      
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
  
  Index: LateralTCPSender.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LateralTCPSender.java     15 May 2002 19:38:32 -0000      1.3
  +++ LateralTCPSender.java     17 May 2002 14:12:52 -0000      1.4
  @@ -33,7 +33,7 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Aaron Smuts</a>
    * @created January 15, 2002
  - * @version $Id: LateralTCPSender.java,v 1.3 2002/05/15 19:38:32 asmuts Exp $
  + * @version $Id: LateralTCPSender.java,v 1.4 2002/05/17 14:12:52 jtaylor Exp $
    */
   public class LateralTCPSender
   {
  @@ -207,8 +207,6 @@
       {
           ICacheElement ice = null;
   
  -        log.debug( "sendAndReceive led" );
  -
           if ( led == null )
           {
               return null;
  @@ -217,7 +215,6 @@
           if ( address == null )
           {
               throw new IOException( "No remote host is set for LateralTCPSender." );
  -            //return;
           }
   
           if ( oos != null )
  
  
  
  1.4       +5 -22     
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheListener.java
  
  Index: RemoteCacheListener.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheListener.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RemoteCacheListener.java  8 Apr 2002 22:58:14 -0000       1.3
  +++ RemoteCacheListener.java  17 May 2002 14:12:52 -0000      1.4
  @@ -206,14 +206,8 @@
   
               getCacheManager();
               ICompositeCache cache = ( ICompositeCache ) cacheMgr.getCache( 
cb.getCacheName() );
  -//            if ( this.irca.getLocalClusterConsistency() && 
this.irca.getRemoteType() != irca.CLUSTER )
  -//            {
  -            cache.update( cb, CacheConstants.EXCLUDE_REMOTE_CACHE );
  -//            }
  -//            else
  -//            {
  -//                cache.update( cb, ICache.INCLUDE_REMOTE_CACHE );
  -//            }
  +
  +            cache.localUpdate( cb );
           }
   
           return;
  @@ -237,19 +231,8 @@
   
           getCacheManager();
           Cache cache = ( Cache ) cacheMgr.getCache( cacheName );
  -        // If cluster updates another cluster, then update listeners to that
  -        // cluster.
  -        // Do not communicate with cluster except via server.
  -        // separates the remote from the local.  Must run a server to
  -        // cluster, else it can be run inside a local.
  -//        if ( this.irca.getLocalClusterConsistency() && this.irca.getRemoteType() 
!= irca.CLUSTER )
  -//        {
  -        cache.remove( key, CacheConstants.REMOTE_INVOKATION );
  -//        }
  -//        else
  -//        {
  -//            cache.remove( key, cache.LOCAL_INVOKATION );
  -//        }
  +
  +        cache.localRemove( key );
       }
   
   
  @@ -276,7 +259,7 @@
               log.debug( "handleDispose> cacheName=" + cacheName );
           }
           CacheHub cm = ( CacheHub ) cacheMgr;
  -        cm.freeCache( cacheName, CacheConstants.REMOTE_INVOKATION );
  +        cm.freeCache( cacheName, true);
       }
   
   
  
  
  
  1.4       +2 -2      
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/group/RemoteGroupCacheListener.java
  
  Index: RemoteGroupCacheListener.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/group/RemoteGroupCacheListener.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RemoteGroupCacheListener.java     8 Apr 2002 22:58:15 -0000       1.3
  +++ RemoteGroupCacheListener.java     17 May 2002 14:12:52 -0000      1.4
  @@ -122,7 +122,7 @@
                       {
                           log.debug( "cache = " + cache );
                       }
  -                    cache.updateGroupAttrNameSet( ( GroupAttrName ) cb.getKey(), 
CacheConstants.REMOTE_INVOKATION, false );
  +                    cache.updateGroupAttrNameSet( ( GroupAttrName ) cb.getKey(), 
true, false );
   
                       log.debug( "Adding to attrNameSet " );
                   }
  @@ -142,7 +142,7 @@
   
                       getCacheManager();
                       ICompositeCache cache = ( ICompositeCache ) cacheMgr.getCache( 
irca.getCacheName() );
  -                    cache.update( cb, CacheConstants.REMOTE_INVOKATION );
  +                    cache.localUpdate( cb );
   
                   }
   
  
  
  
  1.6       +8 -19     
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
  
  Index: RemoteCacheServer.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RemoteCacheServer.java    12 Apr 2002 02:13:33 -0000      1.5
  +++ RemoteCacheServer.java    17 May 2002 14:12:52 -0000      1.6
  @@ -279,7 +279,8 @@
                           {
                               log.debug( "not updating clusters 
**************************************" );
                           }
  -                        c.update( item, CacheConstants.REMOTE_INVOKATION );
  +
  +                        c.localUpdate( item );
                       }
                       else
                       {
  @@ -287,7 +288,8 @@
                           {
                               log.debug( "updating clusters 
**************************************" );
                           }
  -                        c.update( item, CacheConstants.LOCAL_INVOKATION );
  +
  +                        c.update( item );
                       }
                   }
                   catch ( Exception oee )
  @@ -412,21 +414,8 @@
           else
           {
               ICompositeCache c = ( ICompositeCache ) cacheDesc.cache;
  -//            if ( fromCluster )
  -//            {
  -            return c.get( key, CacheConstants.REMOTE_INVOKATION );
  -//            }
  -//            else
  -//            {
  -//                if ( this.rcsa.getAllowClusterGet() )
  -//                {
  -//                    return c.get( key, container, ICache.LOCAL_INVOKATION );
  -//                }
  -//                else
  -//                {
  -//                    return c.get( key, container, ICache.REMOTE_INVOKATION );
  -//                }
  -//            }
  +
  +            return c.localGet( key );
           }
       }
   
  @@ -473,7 +462,7 @@
                       {
                           log.debug( "not updating clusters 
**************************************" );
                       }
  -                    removeSuccess = c.remove( key, CacheConstants.REMOTE_INVOKATION 
);
  +                    removeSuccess = c.localRemove( key );
                   }
                   else
                   {
  @@ -481,7 +470,7 @@
                       {
                           log.debug( "updating clusters 
**************************************" );
                       }
  -                    removeSuccess = c.remove( key, CacheConstants.LOCAL_INVOKATION 
);
  +                    removeSuccess = c.remove( key );
                   }
   
                   if ( removeSuccess )
  
  
  
  1.4       +3 -3      
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerListener.java
  
  Index: RemoteCacheServerListener.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerListener.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RemoteCacheServerListener.java    8 Apr 2002 22:58:15 -0000       1.3
  +++ RemoteCacheServerListener.java    17 May 2002 14:12:52 -0000      1.4
  @@ -188,7 +188,7 @@
               }
           }
           ICompositeCache cache = ( ICompositeCache ) cacheMgr.getCache( 
irca.getCacheName() );
  -        cache.update( cb, false );
  +        cache.localUpdate( cb );
       }
   
   
  @@ -214,7 +214,7 @@
           // interface limitation here
   
           Cache cache = ( Cache ) cacheMgr.getCache( cacheName );
  -        cache.remove( key, CacheConstants.REMOTE_INVOKATION );
  +        cache.localRemove( key );
       }
   
   
  @@ -241,7 +241,7 @@
               log.debug( "handleDispose> cacheName=" + cacheName );
           }
           CacheHub cm = ( CacheHub ) cacheMgr;
  -        cm.freeCache( cacheName, CacheConstants.REMOTE_INVOKATION );
  +        cm.freeCache( cacheName, true );
       }
   
   
  
  
  
  1.4       +1 -31     
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/CacheConstants.java
  
  Index: CacheConstants.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/CacheConstants.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CacheConstants.java       12 Apr 2002 01:39:57 -0000      1.3
  +++ CacheConstants.java       17 May 2002 14:12:52 -0000      1.4
  @@ -4,41 +4,11 @@
    * Constants used throughout the JCS cache engine
    *
    * @author jtaylor
  - * @version $Id: CacheConstants.java,v 1.3 2002/04/12 01:39:57 jtaylor Exp $
  + * @version $Id: CacheConstants.java,v 1.4 2002/05/17 14:12:52 jtaylor Exp $
    */
   public interface CacheConstants
   {
       public static final String DEFAULT_CONFIG = "/cache.ccf";
  -
  -    /**
  -     * Where the current activity came from. This effects whether the remote
  -     * will be included. Prevents remote-local loops.
  -     */
  -    public static final boolean REMOTE_INVOKATION = true;
  -
  -    /**
  -     * Where the current activity came from. This effects whether the remote
  -     * will be included. Prevents remote-local loops.
  -     */
  -    public static final boolean LATERAL_INVOKATION = true;
  -
  -    /**
  -     * Where the current activity came from. This effects whether the remote
  -     * will be included. Prevents remote-local loops.
  -     */
  -    public static final boolean LOCAL_INVOKATION = !REMOTE_INVOKATION;
  -
  -    /** Whether the update should propagate to the remote */
  -    public static final boolean INCLUDE_REMOTE_CACHE = true;
  -
  -    /** Whether the update should propagate to the remote */
  -    public static final boolean EXCLUDE_REMOTE_CACHE = !INCLUDE_REMOTE_CACHE;
  -
  -    /** Description of the Field */
  -    public static final boolean MULTICAST_ON = true;
  -
  -    /** Description of the Field */
  -    public static final boolean MULTICAST_OFF = false;
   
       /** Cache alive status. */
       public final static int STATUS_ALIVE = 1;
  
  
  
  1.4       +3 -4      
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/CacheEventQueue.java
  
  Index: CacheEventQueue.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/CacheEventQueue.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CacheEventQueue.java      14 May 2002 15:20:43 -0000      1.3
  +++ CacheEventQueue.java      17 May 2002 14:12:52 -0000      1.4
  @@ -285,15 +285,14 @@
   
                       if ( log.isDebugEnabled() )
                       {
  -                      log.debug( "r from take() = " + r );
  +                        log.debug( "r from take() = " + r );
                       }
   
                   }
                   catch ( InterruptedException e )
                   {
  -                    // We were interrupted, so terminate gracefully.
  -
  -                    this.destroy();
  +                    // We were interrupted, just continue -- the while loop
  +                    // will exit if we have been properly destroyed.
                   }
   
                   if ( !destroyed && r != null )
  
  
  
  1.5       +4 -45     
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/behavior/ICompositeCache.java
  
  Index: ICompositeCache.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/behavior/ICompositeCache.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ICompositeCache.java      13 May 2002 22:16:18 -0000      1.4
  +++ ICompositeCache.java      17 May 2002 14:12:53 -0000      1.5
  @@ -20,58 +20,19 @@
    */
   public interface ICompositeCache extends ICache
   {
  -
  -    /** Puts an item to the cache. */
  -    public void update( ICacheElement ce )
  -        throws IOException;
  -
  -
  -    /** Description of the Method */
  -    public void update( ICacheElement ce, boolean localInvocation )
  -        throws IOException;
  -
  -    /** Allows the exclusion of non local caches. */
  -    public void updateExclude( ICacheElement ce, boolean excludeRemote )
  +    public ICacheElement localGet( Serializable key )
           throws IOException;
   
  -    /** Description of the Method */
  -    public boolean remove( Serializable key )
  +    public void localUpdate( ICacheElement ce )
           throws IOException;
   
  -
  -    /** Description of the Method */
  -    public boolean remove( Serializable key, boolean localInvocation )
  +    public boolean localRemove( Serializable key )
           throws IOException;
   
  -
  -    /** allows a get request to stay local * */
  -    public ICacheElement get( Serializable key, boolean localInvocation )
  +    public void localRemoveAll()
           throws IOException;
   
       /**
  -     * Returns the current cache size.
  -     *
  -     * @return The size value
  -     */
  -    public int getSize();
  -
  -
  -    /**
  -     * Returns the cache status.
  -     *
  -     * @return The status value
  -     */
  -    public int getStatus();
  -
  -
  -    /**
  -     * Returns the cache name.
  -     *
  -     * @return The cacheName value
  -     */
  -    public String getCacheName();
  -
  -    /**
        * Adds an  ElementEvent  to be handled
        *
        * @param hand The IElementEventHandler
  @@ -79,6 +40,4 @@
        */
       public void addElementEvent( IElementEventHandler hand, IElementEvent event )
           throws IOException;
  -
  -
   }
  
  
  
  1.12      +62 -162   
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/control/Cache.java
  
  Index: Cache.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/control/Cache.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Cache.java        14 May 2002 17:55:35 -0000      1.11
  +++ Cache.java        17 May 2002 14:12:53 -0000      1.12
  @@ -91,8 +91,7 @@
    *
    *@author     <a href="mailto:[EMAIL PROTECTED]";>Aaron Smuts</a>
    *@author     <a href="mailto:[EMAIL PROTECTED]";>James Taylor</a>
  - *@created    May 13, 2002
  - *@version    $Id: Cache.java,v 1.11 2002/05/14 17:55:35 asmuts Exp $
  + *@version    $Id: Cache.java,v 1.12 2002/05/17 14:12:53 jtaylor Exp $
    */
   public class Cache
        implements ICache, ICompositeCache, Serializable
  @@ -182,113 +181,6 @@
       }
   
       /**
  -     *  Description of the Method
  -     *
  -     *@param  ce
  -     *@deprecated
  -     *@see           this will become protected
  -     */
  -    public void add( ICacheElement ce )
  -    {
  -        try
  -        {
  -            memCache.update( ce );
  -        }
  -        catch ( Exception e )
  -        {
  -            log.error( e );
  -        }
  -        return;
  -    }
  -
  -    /**
  -     *  Put in cache and configured auxiliaries.
  -     *
  -     *@param  key
  -     *@param  val
  -     *@exception  IOException
  -     */
  -    public void put( Serializable key, Serializable val )
  -        throws IOException
  -    {
  -        put( key, val, ( IElementAttributes ) this.attr.copy() );
  -
  -        return;
  -    }
  -
  -    /**
  -     *  Description of the Method
  -     *
  -     *@param  key              Cache key
  -     *@param  val              Value to cache
  -     *@param  attr             Element attributes
  -     *@exception  IOException
  -     */
  -    public void put( Serializable key,
  -                     Serializable val,
  -                     IElementAttributes attr )
  -        throws IOException
  -    {
  -
  -        if ( key == null || val == null )
  -        {
  -            NullPointerException npe =
  -                new NullPointerException( "key=" + key + " and val=" + val +
  -                " must not be null." );
  -
  -            log.error( "Key or value was null. Exception will be thrown", npe );
  -
  -            throw npe;
  -        }
  -
  -        try
  -        {
  -            updateCaches( key, val, attr );
  -        }
  -        catch ( IOException ioe )
  -        {
  -            log.error( "Failed updating caches", ioe );
  -        }
  -        return;
  -    }
  -
  -    /**
  -     *  Description of the Method
  -     *
  -     *@param  key              Cache key
  -     *@param  val              Value to cache
  -     *@param  attr             Element attributes
  -     *@exception  IOException
  -     */
  -    protected synchronized void updateCaches( Serializable key,
  -                                              Serializable val,
  -                                              IElementAttributes attr )
  -        throws IOException
  -    {
  -        updateCaches( key, val, attr, CacheConstants.INCLUDE_REMOTE_CACHE );
  -    }
  -
  -    /**
  -     *  Description of the Method
  -     *
  -     *@param  key
  -     *@param  val
  -     *@param  attr
  -     *@param  updateRemoteCache
  -     *@exception  IOException
  -     */
  -    protected synchronized void updateCaches( Serializable key,
  -                                              Serializable val,
  -                                              IElementAttributes attr,
  -                                              boolean updateRemoteCache )
  -        throws IOException
  -    {
  -        CacheElement ce = new CacheElement( cacheName, key, val );
  -        ce.setElementAttributes( attr );
  -        updateExclude( ce, updateRemoteCache );
  -    }
  -
  -    /**
        *  Standard update method
        *
        *@param  ce
  @@ -297,20 +189,19 @@
       public synchronized void update( ICacheElement ce )
           throws IOException
       {
  -        update( ce, CacheConstants.INCLUDE_REMOTE_CACHE );
  +        update( ce, false );
       }
   
       /**
  -     *  Description of the Method
  +     *  Standard update method
        *
  -     *@param  updateRemoteCache  Should the nonlocal caches be updated
        *@param  ce
        *@exception  IOException
        */
  -    public void update( ICacheElement ce, boolean updateRemoteCache )
  +    public synchronized void localUpdate( ICacheElement ce )
           throws IOException
       {
  -        updateExclude( ce, updateRemoteCache );
  +        update( ce, true );
       }
   
       /**
  @@ -320,7 +211,7 @@
        *@param  updateRemoteCache
        *@exception  IOException
        */
  -    public synchronized void updateExclude( ICacheElement ce, boolean 
updateRemoteCache )
  +    protected synchronized void update( ICacheElement ce, boolean localOnly )
           throws IOException
       {
   
  @@ -379,7 +270,7 @@
                   }
   
                   if ( ce.getElementAttributes().getIsRemote()
  -                     && updateRemoteCache )
  +                     && ! localOnly )
                   {
                       try
                       {
  @@ -411,7 +302,7 @@
                   }
                   if ( cacheAttr.getUseLateral()
                        && ce.getElementAttributes().getIsLateral()
  -                     && updateRemoteCache )
  +                     && ! localOnly )
                   {
                       // later if we want a multicast, possibly delete abnormal 
broadcaster
                       // DISTRIBUTE LATERALLY
  @@ -527,49 +418,37 @@
           }
   
       }
  -    // end spoolToDisk
   
       /**
  -     *  Gets an item from the cache, and make it the first in the link list.
  -     *
  -     *@param  key
  -     *@return                              The cacheElement value
  -     *@exception  ObjectNotFoundException
  -     *@exception  IOException
  +     * @see ICache#get
        */
  -    public Serializable getCacheElement( Serializable key )
  -        throws ObjectNotFoundException, IOException
  +    public ICacheElement get( Serializable key )
       {
  -        return get( key, CacheConstants.LOCAL_INVOKATION );
  +        return get( key, false );
       }
  -    // end get ce
   
       /**
  -     *  Description of the Method
  -     *
  -     *@param  key
  -     *@return
  +     * @see ICompositeCache#localGet
        */
  -    public ICacheElement get( Serializable key )
  +    public ICacheElement localGet( Serializable key )
       {
  -        return get( key, CacheConstants.LOCAL_INVOKATION );
  +        return get( key, true );
       }
   
       /**
        *  Description of the Method
        *
        *@param  key
  -     *@param  invocation
  +     *@param  localOnly
        *@return
        */
  -    public ICacheElement get( Serializable key, boolean invocation )
  +    protected ICacheElement get( Serializable key, boolean localOnly )
       {
           ICacheElement element = null;
   
           if ( log.isDebugEnabled() )
           {
  -            log.debug( "get: key = " + key + ", local = "
  -                 + ( invocation == CacheConstants.LOCAL_INVOKATION ) );
  +            log.debug( "get: key = " + key + ", localOnly = " + localOnly );
           }
   
           try
  @@ -589,16 +468,16 @@
   
                       if ( aux != null )
                       {
  +                        long cacheType = aux.getCacheType();
   
  -                        if ( ( invocation == CacheConstants.LOCAL_INVOKATION )
  -                             || aux.getCacheType() == aux.DISK_CACHE )
  +                        if ( ! localOnly || cacheType == aux.DISK_CACHE )
                           {
                               if ( log.isDebugEnabled() )
                               {
                                   log.debug( "Attempting to get from aux: "
                                        + aux.getCacheName()
                                        + " which is of type: "
  -                                     + aux.getCacheType() );
  +                                     + cacheType );
                               }
   
                               try
  @@ -721,16 +600,20 @@
       }
   
       /**
  -     *  Removes an item from the cache.
  -     *
  -     *@param  key
  -     *@return
  +     * @see ICache#remove
        */
       public boolean remove( Serializable key )
       {
  -        return remove( key, CacheConstants.LOCAL_INVOKATION );
  +        return remove( key, false );
       }
   
  +    /**
  +     * @see ICompositeCache#localRemove
  +     */
  +    public boolean localRemove( Serializable key )
  +    {
  +        return remove( key, true );
  +    }
   
       /**
        *  fromRemote: If a remove call was made on a cache with both, then the
  @@ -748,18 +631,13 @@
        *  will need to build in an identifier to specify the source of a removal.
        *
        *@param  key
  -     *@param  nonLocal
  +     *@param  localOnly
        *@return
        */
   
  -    public synchronized boolean remove( Serializable key, boolean nonLocal )
  +    protected synchronized boolean remove( Serializable key,
  +                                           boolean localOnly )
       {
  -
  -        if ( log.isDebugEnabled() )
  -        {
  -            log.debug( "remove> key=" + key + ", nonLocal=" + nonLocal );
  -        }
  -
           boolean removed = false;
   
           try
  @@ -780,11 +658,12 @@
               {
                   continue;
               }
  -            // avoid notification dead loop.
  +
               int cacheType = aux.getCacheType();
   
               // for now let laterals call remote remove but not vice versa
  -            if ( nonLocal && ( cacheType == REMOTE_CACHE || cacheType == 
LATERAL_CACHE ) )
  +
  +            if ( localOnly && ( cacheType == REMOTE_CACHE || cacheType == 
LATERAL_CACHE ) )
               {
                   continue;
               }
  @@ -811,12 +690,30 @@
           }
           return removed;
       }
  -    // end remove
   
       /**
  -     *  Removes all cached items.
  +     * @see ICache#removeAll
        */
  -    public synchronized void removeAll()
  +    public void removeAll()
  +        throws IOException
  +    {
  +        removeAll( false );
  +    }
  +
  +    /**
  +     * @see ICompositeCache#removeAll
  +     */
  +    public void localRemoveAll()
  +        throws IOException
  +    {
  +        removeAll( true );
  +    }
  +
  +    /**
  +     * Removes all cached items.
  +     */
  +    protected synchronized void removeAll( boolean localOnly )
  +        throws IOException
       {
   
           try
  @@ -833,7 +730,10 @@
           {
               ICache aux = auxCaches[i];
   
  -            if ( aux != null && aux.getCacheType() == ICache.DISK_CACHE )
  +            int cacheType = aux.getCacheType();
  +
  +            if ( aux != null
  +                 && ( cacheType == ICache.DISK_CACHE || ! localOnly ) )
               {
                   try
                   {
  @@ -854,7 +754,7 @@
        */
       public void dispose()
       {
  -        dispose( CacheConstants.LOCAL_INVOKATION );
  +        dispose( false );
       }
   
       /**
  @@ -1083,7 +983,7 @@
       public IElementAttributes getElementAttributes( Serializable key )
           throws CacheException, IOException
       {
  -        CacheElement ce = ( CacheElement ) getCacheElement( key );
  +        CacheElement ce = ( CacheElement ) get( key );
           if ( ce == null )
           {
               throw new ObjectNotFoundException( "key " + key + " is not found" );
  
  
  
  1.8       +2 -2      
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/control/CacheHub.java
  
  Index: CacheHub.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/control/CacheHub.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- CacheHub.java     12 Apr 2002 13:03:12 -0000      1.7
  +++ CacheHub.java     17 May 2002 14:12:53 -0000      1.8
  @@ -340,7 +340,7 @@
       /** */
       public void freeCache( String name )
       {
  -        freeCache( name, CacheConstants.LOCAL_INVOKATION );
  +        freeCache( name, false );
       }
   
       /** */
  @@ -363,7 +363,7 @@
       /** */
       public void release()
       {
  -        release( CacheConstants.LOCAL_INVOKATION );
  +        release( false );
       }
   
       /** */
  
  
  
  1.7       +56 -88    
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/control/group/GroupCache.java
  
  Index: GroupCache.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/control/group/GroupCache.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- GroupCache.java   12 Apr 2002 13:03:12 -0000      1.6
  +++ GroupCache.java   17 May 2002 14:12:53 -0000      1.7
  @@ -154,7 +154,7 @@
        */
       public ICacheElement get( Serializable key )
       {
  -        return get( key, CacheConstants.LOCAL_INVOKATION );
  +        return get( key, false );
       }
   
       /**
  @@ -183,7 +183,7 @@
               log.debug( this.getCacheName() + " getting "
                          + key + " from super " );
   
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +            if ( invocation == false )
               {
                   log.debug( "invokation is LOCAL" );
               }
  @@ -206,7 +206,7 @@
        */
       public ICacheElement getGAN( GroupAttrName key )
       {
  -        return getGAN( key, CacheConstants.LOCAL_INVOKATION );
  +        return getGAN( key, false );
       }
   
       /**
  @@ -221,7 +221,7 @@
       {
           if ( log.isDebugEnabled() )
           {
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +            if ( invocation == false )
               {
                   log.debug( "invokation is LOCAL" );
               }
  @@ -257,7 +257,7 @@
       // get list from remote if it isn't present
       public ICacheElement getGI( GroupId gid )
       {
  -        return getGI( gid, CacheConstants.LOCAL_INVOKATION );
  +        return getGI( gid, false );
       }
   
       /**
  @@ -271,7 +271,7 @@
           if ( log.isDebugEnabled() )
           {
               log.debug( "getGi(gid,container,invocation)" );
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +            if ( invocation == false )
               {
                   log.debug( "invocation is LOCAL" );
               }
  @@ -284,8 +284,17 @@
           readLock( gid.key );
           try
           {
  -            //obj = super.get(gid.key, container);
  -            obj = systemGroupIdCache.get( gid.key, invocation );
  +            if ( invocation )
  +            {
  +                // Invocation is NOT local
  +                obj = systemGroupIdCache.localGet( gid.key );
  +            }
  +            else
  +            {
  +                // Invocation is local
  +                obj = systemGroupIdCache.get( gid.key );
  +            }
  +
               if ( log.isDebugEnabled() )
               {
                   log.debug( "getGi: got obj " + obj );
  @@ -384,7 +393,7 @@
               //updateCaches( key, val, attr );
               CacheElement ce = new CacheElement( this.getCacheName(), key, val );
               ce.setElementAttributes( attr );
  -            super.update( ce, CacheConstants.INCLUDE_REMOTE_CACHE );
  +            super.update( ce );
   
           }
           catch ( IOException ioe )
  @@ -429,7 +438,7 @@
               // problem super calls back up and the last instruction gets confused
               CacheElement ce = new CacheElement( this.getCacheName(), key, val );
               ce.setElementAttributes( attrE );
  -            super.update( ce, CacheConstants.INCLUDE_REMOTE_CACHE );
  +            super.update( ce );
           }
           catch ( IOException ioe )
           {
  @@ -467,7 +476,7 @@
               // must make sure you call the sure here
               // updateCaches( key, val, attrE, ICache.INCLUDE_REMOTE_CACHE );
               // problem super calls back up and the last instruction gets confused
  -            super.update( ce, CacheConstants.INCLUDE_REMOTE_CACHE );
  +            super.update( ce );
           }
           catch ( IOException ioe )
           {
  @@ -477,12 +486,9 @@
   
   
       /**
  -     * Description of the Method
  -     *
  -     * @param invocation Is the originating method call from a local source
  +     * Update
        */
  -    // PROBLEM CACHE HAS THE SAME METHOD AND THE 2nd arg is updateRemote
  -    public synchronized void update( ICacheElement ce, boolean invocation )
  +    public synchronized void update( ICacheElement ce, boolean localOnly )
           throws IOException
       {
   
  @@ -494,17 +500,9 @@
                   if ( log.isDebugEnabled() )
                   {
                       log.debug( "update(ce,invocation) >putting via ga method" );
  -                    if ( invocation == CacheConstants.LOCAL_INVOKATION )
  -                    {
  -                        log.debug( "invocation is LOCAL" );
  -                    }
  -                    else
  -                    {
  -                        log.debug( "invocation is NOT Local" );
  -                    }
                   }
                   IElementAttributes attrE = ( IElementAttributes ) this.attr.copy();
  -                putGAN( ( GroupAttrName ) key, ce.getVal(), attrE, invocation );
  +                putGAN( ( GroupAttrName ) key, ce.getVal(), attrE, localOnly );
               }
               catch ( IOException ioe )
               {
  @@ -524,18 +522,7 @@
   
           try
           {
  -            // update should go remote if locally invoked
  -            boolean updateRemote = false;
  -            // DECIDE WHAT TO DO WITH THE LIST
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  -            {
  -                updateRemote = CacheConstants.INCLUDE_REMOTE_CACHE;
  -            }
  -            else
  -            {
  -                updateRemote = CacheConstants.EXCLUDE_REMOTE_CACHE;
  -            }
  -            super.update( ce, updateRemote );
  +            super.update( ce, localOnly );
           }
           catch ( IOException ioe )
           {
  @@ -580,7 +567,7 @@
       {
           log.debug( "in putGAN( gan,val,attr) " );
   
  -        putGAN( key, val, attrE, CacheConstants.LOCAL_INVOKATION );
  +        putGAN( key, val, attrE, false );
       }
   
       /**
  @@ -590,7 +577,7 @@
        */
       public void putGAN( GroupAttrName key, Serializable val,
                           IElementAttributes attrE,
  -                        boolean invocation )
  +                        boolean localOnly )
           throws IOException
       {
   
  @@ -598,14 +585,6 @@
           {
               //p( "in putGAN( gan,val,attr,boolean updateRemote) " );
               log.debug( "in putGAN( gan,val,attr,boolean invocation) " );
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  -            {
  -                log.debug( "invocation is LOCAL" );
  -            }
  -            else
  -            {
  -                log.debug( "invocation is NOT Local" );
  -            }
           }
   
           writeLock( key.groupId );
  @@ -622,23 +601,12 @@
                   log.debug( "putGAN( gan,val,attr,boolean invocation) > updating 
group attribute via super" );
               }
   
  -            // SEND THE ELEMENT IF THE INVOCATION WAS LOCAL
  -            // decide what to do with this item
  -            boolean updateRemote = false;
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  -            {
  -                updateRemote = CacheConstants.INCLUDE_REMOTE_CACHE;
  -            }
  -            else
  -            {
  -                updateRemote = CacheConstants.EXCLUDE_REMOTE_CACHE;
  -            }
  -            super.update( ce, updateRemote );
  +            super.update( ce, localOnly );
   
               // UPDATE THE ATTRIBUTENAME LIST, get it first
               GroupId groupId = new GroupId( this.getCacheName(), key.groupId );
               HashSet attrNameSet = null;
  -            attrNameSet = ( HashSet ) systemGroupIdCache.get( groupId.key, false );
  +            attrNameSet = ( HashSet ) systemGroupIdCache.get( groupId.key );
   
               if ( attrNameSet == null )
               {
  @@ -656,9 +624,8 @@
   
               // DO NOT SEND THE UPDATE LIST REMOTELY
               // THE ELEMENT WILL BE SENT AND THE LIST MAINTAINED REMOTELY
  -            systemGroupIdCache.updateExclude( ceID, 
CacheConstants.EXCLUDE_REMOTE_CACHE );
  -            // could use the updateGroupAttr method?
   
  +            systemGroupIdCache.localUpdate( ceID );
           }
           finally
           {
  @@ -704,7 +671,7 @@
               ceID.setElementAttributes( attrE );
               //updateCaches(groupId.key, attrNameSet, attrE );
               //super.update( ceID, EXCLUDE_REMOTE_CACHE );
  -            systemGroupIdCache.update( ceID, CacheConstants.EXCLUDE_REMOTE_CACHE );
  +            systemGroupIdCache.localUpdate( ceID );
   
           }
           catch ( IOException ioe )
  @@ -721,7 +688,7 @@
   
           // if expired super will call remove and we can't have a lock
           // need a third method
  -        return remove( key, CacheConstants.LOCAL_INVOKATION );
  +        return remove( key, false);
       }// rmove
   
       /**
  @@ -739,7 +706,7 @@
               if ( log.isDebugEnabled() )
               {
                   log.debug( "calling removeGAN" );
  -                if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +                if ( invocation == false )
                   {
                       log.debug( "invokation is LOCAL" );
                   }
  @@ -757,7 +724,7 @@
               if ( log.isDebugEnabled() )
               {
                   log.debug( "call removeGI" );
  -                if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +                if ( invocation == false )
                   {
                       log.debug( "invokation is LOCAL" );
                   }
  @@ -773,7 +740,7 @@
           if ( log.isDebugEnabled() )
           {
               log.debug( "call super.remove, " + invocation + " for " + key );
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +            if ( invocation == false )
               {
                   log.debug( "invokation is LOCAL" );
               }
  @@ -805,7 +772,7 @@
           if ( log.isDebugEnabled() )
           {
               log.debug( "in removeGAN" );
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +            if ( invocation == false )
               {
                   log.debug( "invocation is LOCAL" );
               }
  @@ -859,8 +826,16 @@
   
           try
           {
  -            ce = ( CacheElement )
  -                systemGroupIdCache.get( groupId.key, invocation );
  +            if ( invocation )
  +            {
  +                // Invocation is NOT local
  +                ce = ( CacheElement ) systemGroupIdCache.localGet( groupId.key );
  +            }
  +            else
  +            {
  +                // Invocation is local
  +                ce = ( CacheElement ) systemGroupIdCache.get( groupId.key );
  +            }
           }
           catch ( IOException ioe )
           {
  @@ -908,7 +883,8 @@
                           }
                           // ALWAYS EXCLUDE THE REMOTE CACHE
                           // TODO: should this be configurable? no
  -                        systemGroupIdCache.updateExclude( ceID, 
CacheConstants.EXCLUDE_REMOTE_CACHE );
  +
  +                        systemGroupIdCache.localUpdate( ceID );
   
                       }
                       catch ( IOException ioe )
  @@ -928,18 +904,16 @@
                           {
                               log.debug( "calling systemGroupIdCache.remove( 
groupId.key, EXCLUDE_REMOTE_CACHE )" );
                           }
  +
                           // unlike insertion, removal should go remote if locally 
invoked
  -                        boolean updateRemote = false;
  -                        // DECIDE WHAT TO DO WITH THE LIST
  -                        if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +                        if ( invocation )
                           {
  -                            updateRemote = CacheConstants.INCLUDE_REMOTE_CACHE;
  +                            systemGroupIdCache.localRemove( groupId.key );
                           }
                           else
                           {
  -                            updateRemote = CacheConstants.EXCLUDE_REMOTE_CACHE;
  +                            systemGroupIdCache.remove( groupId.key );
                           }
  -                        systemGroupIdCache.remove( groupId.key, updateRemote );
                       }
                       catch ( IOException ioe )
                       {
  @@ -958,7 +932,7 @@
       {
           log.debug( "removeGI" );
   
  -        removeGI( groupId, CacheConstants.LOCAL_INVOKATION );
  +        removeGI( groupId, false);
       }
   
       /**
  @@ -990,20 +964,14 @@
           }
           try
           {
  -
  -            // unlike insertion, removal should go remote if locally invoked
  -            boolean updateRemote = false;
  -            // DECIDE WHAT TO DO WITH THE LIST
  -            if ( invocation == CacheConstants.LOCAL_INVOKATION )
  +            if ( invocation )
               {
  -                updateRemote = CacheConstants.INCLUDE_REMOTE_CACHE;
  +                ok = systemGroupIdCache.localRemove( groupId.key );
               }
               else
               {
  -                updateRemote = CacheConstants.EXCLUDE_REMOTE_CACHE;
  +                ok = systemGroupIdCache.remove( groupId.key );
               }
  -            ok = systemGroupIdCache.remove( groupId.key, updateRemote );
  -
           }
           catch ( IOException ioeg )
           {
  @@ -1027,7 +995,7 @@
       public IElementAttributes getElementAttributes( Serializable key )
           throws CacheException, IOException
       {
  -        CacheElement ce = ( CacheElement ) getCacheElement( key );
  +        CacheElement ce = ( CacheElement ) get( key );
           if ( ce == null )
           {
               throw new ObjectNotFoundException( "key " + key + " is not found" );
  
  
  
  1.3       +100 -76   
jakarta-turbine-jcs/src/java/org/apache/jcs/utils/locking/ReadWriteLockManager.java
  
  Index: ReadWriteLockManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/utils/locking/ReadWriteLockManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReadWriteLockManager.java 8 Apr 2002 19:07:59 -0000       1.2
  +++ ReadWriteLockManager.java 17 May 2002 14:12:53 -0000      1.3
  @@ -41,108 +41,58 @@
           lock( id, true );
       }
   
  -    /**
  -     * Release the read/write lock previously placed on the specified resource.
  -     */
  -    public final void done( String id )
  +     /** Places either a read or write lock on the specified resource. */
  +    private void lock( String id, boolean isWrite )
  +        throws InterruptedException
       {
  -        Hashtable ht = getLocks();
  -        RwLockHolder holder = ( RwLockHolder ) ht.get( id );
  +        // For messages
   
  -        if ( holder == null )
  -        {
  +        String lockType = isWrite ? "write" : "read";
   
  -            log.debug( "Method done of " + getClass().getName() + " invoked without 
an outstanding lock; id=" + id );
  -            //System.exit(1);
  -
  -            throw new IllegalStateException( "Method done of " + 
getClass().getName()
  -                 + " invoked without an outstanding lock; id=" + id );
  -        }
  -        holder.rwlock.done();
           if ( log.isDebugEnabled() )
           {
  -            log.debug( "lock done for id = " + id );
  -        }
  -        // Somehow if we don't synchronize while changing the count,
  -        // the count went down below zero!
  -        // Theoretically this should never happen, as a "done" is always preceeded
  -        // by either a read or write lock issued from the very same thread.
  -        // So for the moment, let's blame the JVM and make it work via 
synchronization,
  -        // until futher investigation.
  -        int lcount;
  -        // used to minimize the time spent in the synchronized block.
  -        synchronized ( ht )
  -        {
  -            lcount = --holder.lcount;
  -        }
  -        if ( lcount > 0 )
  -        {
  -            return;
  -        }
  -
  -        //  p("-- holder.lcount=" + holder.lcount);
  -        if ( lcount == 0 )
  -        {
  -            holder.lastInactiveTime = System.currentTimeMillis();
  -            //p("notify: Gargage available");
  -            gc.notifyGarbage();
  -            return;
  +            log.debug( "about to get " + lockType + " lock for id: " + id );
           }
  -        // lcount is negative! should never get here.
  -        /*
  -         * p("holder.lcount went down below zero (" + holder.lcount + ") for id=" + 
id);
  -         * System.exit(1);
  -         */
  -        throw new IllegalStateException( "holder.lcount went down below zero ("
  -             + holder.lcount + ") for id=" + id );
  -    }
   
  -    /** Places either a read or write lock on the specified resource. */
  -    private void lock( String id, boolean isWrite )
  -        throws InterruptedException
  -    {
  -        if ( log.isDebugEnabled() )
  -        {
  -            log.debug( "about to get lock, isWrite=" + isWrite + " for id = " + id 
);
  -        }
           RwLockHolder holder;
  +
  +        ensureGarbageCollectorCreated();
  +
           Hashtable ht = getLocks();
  -        if ( gc == null )
  -        {
  -            synchronized ( this )
  -            {
  -                if ( gc == null )
  -                {
  -                    gc = new RwLockGC( ht );
  -                    gc.setDaemon( true );
  -                    gc.start();
  -                }
  -            }
  -        }
  +
           synchronized ( ht )
           {
               holder = ( RwLockHolder ) ht.get( id );
  +
               if ( holder != null )
               {
                   // Lock already exists.  So just use it.
                   holder.lcount++;
  +
                   if ( log.isDebugEnabled() )
                   {
  -                    log.debug( "++ holder.lcount=" + holder.lcount + ", isWrite=" + 
isWrite + " for id = " + id );
  +                    log.debug( "Incrementing holder count to "
  +                               + holder.lcount + " on "
  +                               + lockType + " lock for id = " + id );
                   }
               }
           }
  +
           if ( holder == null )
           {
               // Lock does not exist.  So create a new one.
  +
               RwLockHolder newHolder = new RwLockHolder( new ReadWriteLock() );
  +
               if ( log.isDebugEnabled() )
               {
  -                log.debug( "holder is null, isWrite=" + isWrite );
  +                log.debug( "Creating new lock holder, lock type: " + lockType );
               }
  +
               synchronized ( ht )
               {
                   holder = ( RwLockHolder ) ht.put( id, newHolder );
  +
                   if ( holder != null )
                   {
                       // Oops, the lock is already created by someone else 
concurrently.
  @@ -157,23 +107,97 @@
                   // no concurrency issue -- the new lock is now used.
                   holder = newHolder;
               }
  +
               if ( log.isDebugEnabled() )
               {
  -                log.debug( ( isWrite ? "Write" : "Read" ) + " lock created for " + 
id );
  +                log.debug( lockType + " lock created for " + id );
               }
           }
  +
           // Be careful not to put the following code into a synchronized block.
  -        // Otherwise, deadlock can easily happen as the writeLock() and readLock() 
may result
  -        // in the ReadWriteLock object being waited!
  +        // Otherwise, deadlock can easily happen as the writeLock() and
  +        // readLock() may result in the ReadWriteLock object being waited!
  +
           if ( isWrite )
           {
  -            holder.rwlock.writeLock();
  +            holder.writeLock();
           }
           else
           {
  -            holder.rwlock.readLock();
  +            holder.readLock();
           }
           return;
  +    }
  +
  +    /** Ensures that the lock garbage collector has been created */
  +    private synchronized void ensureGarbageCollectorCreated()
  +    {
  +        if ( gc == null )
  +        {
  +            gc = new RwLockGC( getLocks() );
  +            gc.setDaemon( true );
  +            gc.start();
  +        }
  +    }
  +
  +    /**
  +     * Release the read/write lock previously placed on the specified resource.
  +     */
  +    public final void done( String id )
  +    {
  +        Hashtable ht = getLocks();
  +
  +        RwLockHolder holder = ( RwLockHolder ) ht.get( id );
  +
  +        if ( holder == null )
  +        {
  +            String message =
  +                "done called without an outstanding lock for id: " + id;
  +
  +            if ( log.isDebugEnabled() )
  +            {
  +                log.debug( message );
  +            }
  +
  +            throw new IllegalStateException( message );
  +        }
  +
  +        holder.done();
  +
  +        if ( log.isDebugEnabled() )
  +        {
  +            log.debug( "lock done for id = " + id );
  +        }
  +        // Somehow if we don't synchronize while changing the count,
  +        // the count went down below zero!
  +        // Theoretically this should never happen, as a "done" is always preceeded
  +        // by either a read or write lock issued from the very same thread.
  +        // So for the moment, let's blame the JVM and make it work via 
synchronization,
  +        // until futher investigation.
  +        int lcount;
  +        // used to minimize the time spent in the synchronized block.
  +        synchronized ( ht )
  +        {
  +            lcount = --holder.lcount;
  +        }
  +
  +        if ( lcount > 0 )
  +        {
  +            return;
  +        }
  +        else if ( lcount == 0 )
  +        {
  +            holder.lastInactiveTime = System.currentTimeMillis();
  +
  +            gc.notifyGarbage();
  +            return;
  +        }
  +        else
  +        {
  +            throw new IllegalStateException(
  +                "holder.lcount went down below zero ("
  +                + holder.lcount + ") for id=" + id );
  +        }
       }
   
       /**
  
  
  
  1.2       +25 -6     
jakarta-turbine-jcs/src/java/org/apache/jcs/utils/locking/RwLockHolder.java
  
  Index: RwLockHolder.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/utils/locking/RwLockHolder.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RwLockHolder.java 7 Apr 2002 16:55:27 -0000       1.1
  +++ RwLockHolder.java 17 May 2002 14:12:53 -0000      1.2
  @@ -10,11 +10,11 @@
    */
   class RwLockHolder
   {
  +    // 10 seconds
       private final static long UNUSED_TIME = 10 * 1000;
  -    // 10 seconds.
   
  -    /** Read/Write lock for a specific resource. */
  -    final ReadWriteLock rwlock;
  +    /** Contained ReadWriteLock */
  +    private final ReadWriteLock rwlock;
   
       /**
        * Number of locks that have been placed on the rwlock and not yet released.
  @@ -24,7 +24,6 @@
       /** Last timestamp when the lcount was zero. */
       long lastInactiveTime = -1;
   
  -
       /**
        * Constructs with a Read/Write lock for a specific resource.
        *
  @@ -35,14 +34,34 @@
           this.rwlock = rwlock;
       }
   
  -
       /**
        * Returns true iff this object satisfies the condition of removing
        * RwLockHolder from the managing ReadWriteLockManager.
        */
       boolean removable( long now )
       {
  -        return lcount == 0 && lastInactiveTime > 0 && now - lastInactiveTime > 
UNUSED_TIME;
  +        return lcount == 0
  +               && lastInactiveTime > 0
  +               && now - lastInactiveTime > UNUSED_TIME;
  +    }
  +
  +    /** @see ReadWriteLock#readLock */
  +    public void readLock() throws InterruptedException
  +    {
  +        rwlock.readLock();
  +    }
  +
  +    /** @see ReadWriteLock#writeLock */
  +    public void writeLock() throws InterruptedException
  +    {
  +        rwlock.writeLock();
  +    }
  +
  +    /** @see ReadWriteLock#done */
  +    public void done()
  +    {
  +        rwlock.done();
       }
  +
   }
   
  
  
  
  1.2       +28 -28    
jakarta-turbine-jcs/src/test/org/apache/jcs/auxiliary/lateral/http/broadcast/LateralCacheTester.java
  
  Index: LateralCacheTester.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/src/test/org/apache/jcs/auxiliary/lateral/http/broadcast/LateralCacheTester.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LateralCacheTester.java   7 Apr 2002 16:55:32 -0000       1.1
  +++ LateralCacheTester.java   17 May 2002 14:12:53 -0000      1.2
  @@ -8,34 +8,34 @@
   public class LateralCacheTester
   {
   
  -    /** Description of the Method */
  -    public static void main( String args[] )
  -    {
  -
  -        String[] servers = {"10.1.17.109", "10.1.17.108"};
  -
  -        try
  -        {
  -
  -            //for ( int i=0; i <100; i++ ) {
  -            String val = "test object value";
  -            LateralCacheThread dct = new LateralCacheThread( "testTable", 
"testkey", val, servers );
  -            dct.setPriority( Thread.NORM_PRIORITY - 1 );
  -            dct.start();
  -
  -            String val2 = "test object value2";
  -            LateralCacheThread dct2 = new LateralCacheThread( "testTable", 
"testkey", val, servers );
  -            dct2.setPriority( Thread.NORM_PRIORITY - 1 );
  -            dct2.start();
  -            //}
  -
  -        }
  -        catch ( Exception e )
  -        {
  -            System.out.println( e.toString() );
  -        }
  -
  -    }
  +//    /** Description of the Method */
  +//    public static void main( String args[] )
  +//    {
  +//
  +//        String[] servers = {"10.1.17.109", "10.1.17.108"};
  +//
  +//        try
  +//        {
  +//
  +//            //for ( int i=0; i <100; i++ ) {
  +//            String val = "test object value";
  +//            LateralCacheThread dct = new LateralCacheThread( "testTable", 
"testkey", val, servers );
  +//            dct.setPriority( Thread.NORM_PRIORITY - 1 );
  +//            dct.start();
  +//
  +//            String val2 = "test object value2";
  +//            LateralCacheThread dct2 = new LateralCacheThread( "testTable", 
"testkey", val, servers );
  +//            dct2.setPriority( Thread.NORM_PRIORITY - 1 );
  +//            dct2.start();
  +//            //}
  +//
  +//        }
  +//        catch ( Exception e )
  +//        {
  +//            System.out.println( e.toString() );
  +//        }
  +//
  +//    }
   
   }
   // end class
  
  
  

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

Reply via email to