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