User: pra     
  Date: 02/02/17 09:55:08

  Modified:    src/main/org/jboss/mq/server MessageCache.java
                        MessageReference.java
  Log:
  * Corrected several bugs in LRUCache and in usage of it.
  * Corrected thread locks. All access in both MessageCache and MessageReference now 
sync on MessageCache. Any changes to this must be tested on at least a dual CPU and 
with 100 000 messages or more, to be shure no threading locks are reintrioduced.
  
  Revision  Changes    Path
  1.16      +61 -26    jbossmq/src/main/org/jboss/mq/server/MessageCache.java
  
  Index: MessageCache.java
  ===================================================================
  RCS file: /cvsroot/jboss/jbossmq/src/main/org/jboss/mq/server/MessageCache.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- MessageCache.java 15 Feb 2002 20:59:53 -0000      1.15
  +++ MessageCache.java 17 Feb 2002 17:55:08 -0000      1.16
  @@ -4,7 +4,6 @@
    * Distributable under LGPL license.
    * See terms of license at gnu.org.
    */
  -
   package org.jboss.mq.server;
   
   import java.io.File;
  @@ -32,15 +31,14 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Hiram Chirino</a>
    * @author <a href="mailto:[EMAIL PROTECTED]";>David Maplesden</a>
  - * @version    $Revision: 1.15 $
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Antman</a>
  + * @version    $Revision: 1.16 $
    */
  -public class MessageCache
  -   extends ServiceMBeanSupport
  -   implements MessageCacheMBean, MBeanRegistration, Runnable
  +public class MessageCache extends ServiceMBeanSupport implements MessageCacheMBean, 
MBeanRegistration, Runnable
   {
      // The cached messages are orded in a LRU linked list
      private LRUCache lruCache = new LRUCache();
  -   
  +  
      // Provides a Unique ID to MessageHanles
      private long messageCounter = 0;
      int cacheHits = 0;
  @@ -72,18 +70,25 @@
       */
      public MessageReference add(SpyMessage message) throws javax.jms.JMSException
      {
  -      log.trace("add lock aquire");
  +      boolean trace = log.isTraceEnabled();
  +      if (trace)
  +         log.trace("add lock aquire");
  +      
  +      MessageReference mh = null;
         synchronized (this)
         {
  -         MessageReference mh = new MessageReference();
  +         mh = new MessageReference();
            mh.init(this, messageCounter++, message);
            lruCache.addMostRecent(mh);
            totalCacheSize++;
            validateSoftReferenceDepth();
  +  
  +         if(trace)
  +            log.trace("add lock release");
   
  -         log.trace("add lock release");
  -         return mh;
         }
  +
  +      return mh;
      }
   
      /**
  @@ -91,13 +96,19 @@
       */
      public void remove(MessageReference mr) throws JMSException
      {
  -      log.trace("remove lock aquire");
  +      boolean trace = log.isTraceEnabled();
  +      if (trace)
  +         log.trace("remove lock aquire");
  +
         synchronized (this)
         {
  -         mr.clear();
  -         lruCache.remove(mr);
  +         mr.clear();//Will remove it from storage if soft
  +         if (mr.hardReference != null)//If message is not hard, dont do lru stuff
  +            lruCache.remove(mr);
            totalCacheSize--;
  -         log.trace("remove lock release");
  +  
  +         if (trace)
  +            log.trace("remove lock release");
         }
      }
   
  @@ -152,10 +163,16 @@
      /**
       * This method is in charge of determining if it time to convert some
       * hard references over to soft references.
  +    *
  +    * It must NOT be called by a thread holding a lock on a reference wich
  +    * in its turn holds a lock on cache. It WILL lead to deadlocks!!!
       */
      public void validateSoftReferenceDepth() throws JMSException
      {
  -      //log.trace("run lock aquire");
  +      boolean trace = log.isTraceEnabled();
  +      if (trace)
  +         log.trace("run lock aquire");
  +      
         synchronized (this)
         {
   
  @@ -180,35 +197,42 @@
            if (chnageCount > 1)
            {
               if (log.isDebugEnabled())
  -              log.debug("Converting " + chnageCount + " hard ref to to soft refs");
  +               log.debug("Converting " + chnageCount + " hard ref to to soft refs");
               Node leastRecent = lruCache.getLeastRecent();
               for (int i = 0; i < chnageCount && leastRecent != null; i++)
               {
  +               // This is tricky, make soft should really be done outside
  +               // sync on cache
                  MessageReference mr = (MessageReference) leastRecent.data;
                  mr.makeSoft();
  -               lruCache.remove(leastRecent);
  +               lruCache.remove(mr);
                  leastRecent = lruCache.getLeastRecent();
               }
            }
  -         //log.trace("run lock release");
  +         if (trace)
  +            log.trace("run lock release");
         }
  -
      }
   
      /**
       * This gets called when a MessageReference is de-referenced.
       * We will pop it to the top of the RLU
       */
  -   synchronized public void messageReferenceUsedEvent(MessageReference mh, boolean 
wasHard)
  +   void messageReferenceUsedEvent(MessageReference mh, boolean wasHard)
      {
  -      log.trace("messageReferenceUsedEvent lock aquire");
  +      boolean trace = log.isTraceEnabled();
  +      if (trace)
  +         log.trace("messageReferenceUsedEvent lock aquire");
  +      
         synchronized (this)
         {
            if (wasHard)
               lruCache.makeMostRecent(mh);
            else
               lruCache.addMostRecent(mh);
  -         log.trace("messageReferenceUsedEvent lock released");
  +
  +         if (trace)
  +            log.trace("messageReferenceUsedEvent lock released");
         }
      }
   
  @@ -376,6 +400,7 @@
       */
      public void testBigLoad() throws Exception
      {
  +
         MessageCache cache = new MessageCache();
         File tempDir = new File("Temp-" + System.currentTimeMillis());
         tempDir.mkdirs();
  @@ -476,6 +501,7 @@
            }
            ++currentSize;
         }
  +      // Not used anywhere!!
         public void addLeastRecent(Object o)
         {
            Node newNode = new Node();
  @@ -511,14 +537,22 @@
            //remove from linked list
            Node more = node.moreRecent;
            Node less = node.lessRecent;
  -         if(more == null) //means node is mostRecent
  +         if(more == null) {//means node is mostRecent
               mostRecent = less;
  -         else
  +            if (mostRecent != null) {
  +               mostRecent.moreRecent = null;//Mark it as beeing at the top of tree
  +            }
  +         } else {
               more.lessRecent = less;
  -         if(less == null) //means node is leastRecent
  +         }
  +         if(less == null) {//means node is leastRecent
               leastRecent = more;
  -         else
  +            if (leastRecent != null) {
  +               leastRecent.lessRecent = null;//Mark it last in tree
  +            }
  +         } else {
               less.moreRecent = more;
  +         }
            --currentSize;
         }
         public void makeMostRecent(Object o)
  @@ -540,6 +574,7 @@
               less.moreRecent = more;
            //now add back in at most recent position
            node.lessRecent = mostRecent;
  +         node.moreRecent = null;//We are at the top
            mostRecent.moreRecent = node;
            mostRecent = node;
         }
  
  
  
  1.8       +19 -12    jbossmq/src/main/org/jboss/mq/server/MessageReference.java
  
  Index: MessageReference.java
  ===================================================================
  RCS file: /cvsroot/jboss/jbossmq/src/main/org/jboss/mq/server/MessageReference.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- MessageReference.java     13 Dec 2001 22:22:43 -0000      1.7
  +++ MessageReference.java     17 Feb 2002 17:55:08 -0000      1.8
  @@ -25,12 +25,13 @@
    * </ul>
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Hiram Chirino</a>
  - * @version    $Revision: 1.7 $
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Antman</a>
  + * @version    $Revision: 1.8 $
    */
   public class MessageReference implements Comparable
   {
      Logger log = Logger.getLogger(MessageReference.class);
  -   
  +
      static class MessageSoftReference extends SoftReference
      {
         MessageReference parent;
  @@ -85,7 +86,7 @@
         if( trace )
            log.trace("getMessage lock aquire");
   
  -      synchronized (this)
  +      synchronized (messageCache)
         {
            if (hardReference == null)
            {
  @@ -120,7 +121,7 @@
         boolean trace = log.isTraceEnabled();
         if( trace )
            log.trace("clear lock aquire");
  -      synchronized (this)
  +      synchronized (messageCache)
         {
            if (isStored)
            {
  @@ -131,18 +132,24 @@
               log.trace("clear lock relased");
         }
      }
  -   
  -   public synchronized void invalidate() throws JMSException
  +    
  +   public void invalidate() throws JMSException
      {
         clear(); // Clear out the disk copy
      }
   
  -   synchronized void makeSoft() throws JMSException
  +   void makeSoft() throws JMSException
      {
  +      // Called from MessageCache, either throug a reference (resulting in
  +      // other references beeing called) or by the softner.
  +      // Basically means that is a locking issue place. We need to sync
  +      // on the message cache.
         boolean trace = log.isTraceEnabled();
         if( trace )
            log.trace("makeSoft lock aquire");
  -      synchronized (this)
  +      // You are only allowed to make something soft if you own a monitor
  +      // on messageCache
  +      synchronized (messageCache)
         {
            if (softReference != null)
               return;
  @@ -168,13 +175,13 @@
               log.trace("makeSoft lock released");
         }
      }
  -
  -   synchronized void makeHard() throws JMSException
  + 
  +   void makeHard() throws JMSException
      {
         boolean trace = log.isTraceEnabled();
         if( trace )
            log.trace("makeHard lock aquire");
  -      synchronized (this)
  +      synchronized (messageCache)
         {
            // allready hard
            if (hardReference != null)
  @@ -233,4 +240,4 @@
         return (int) (messageId - sm.messageId);
      }
      
  -}
  \ No newline at end of file
  +}
  
  
  

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

Reply via email to