You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2010/10/30 00:44:53 UTC
svn commit: r1028935 - in /tomcat/trunk/java/org/apache/jasper:
compiler/JspRuntimeContext.java servlet/JspServletWrapper.java
util/FastRemovalDequeue.java
Author: rjung
Date: Fri Oct 29 22:44:52 2010
New Revision: 1028935
URL: http://svn.apache.org/viewvc?rev=1028935&view=rev
Log:
Changes to FastRemovalDequeue:
- Make queue thread safe and remove external synchronisation
- Provide maximal size to queue
- Include size checking when adding entries
- Return handle to displaced entries when queue overflows
while adding a new entry
- Explicitely invalidate queue entries on removal by using
new field "valid"
Changes to JspRuntimeContext:
- Initialize FastRemovalDequeue with correct size
- No more external synchronisation for FastRemovalDequeue
- Private utility method to unload a wrapper
- Check for displaced wrapper when adding a new wrapper
to the queue and unload it
Changes to JspServletWrapper:
- No more explicit overflow check for the queue. It's now
done implicitely when adding to the queue.
Modified:
tomcat/trunk/java/org/apache/jasper/compiler/JspRuntimeContext.java
tomcat/trunk/java/org/apache/jasper/servlet/JspServletWrapper.java
tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java
Modified: tomcat/trunk/java/org/apache/jasper/compiler/JspRuntimeContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/JspRuntimeContext.java?rev=1028935&r1=1028934&r2=1028935&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/JspRuntimeContext.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/JspRuntimeContext.java Fri Oct 29 22:44:52 2010
@@ -155,6 +155,11 @@ public final class JspRuntimeContext {
&& options.getCheckInterval() > 0) {
lastCheck = System.currentTimeMillis();
}
+
+ if (options.getMaxLoadedJsps() > 0) {
+ jspQueue = new FastRemovalDequeue<JspServletWrapper>(options.getMaxLoadedJsps());
+ }
+
}
// ----------------------------------------------------- Instance Variables
@@ -178,7 +183,7 @@ public final class JspRuntimeContext {
/**
* Keeps JSP pages ordered by last access.
*/
- private FastRemovalDequeue<JspServletWrapper> jspQueue = new FastRemovalDequeue<JspServletWrapper>();
+ private FastRemovalDequeue<JspServletWrapper> jspQueue = null;
// ------------------------------------------------------ Public Methods
@@ -213,15 +218,18 @@ public final class JspRuntimeContext {
/**
* Push a newly compiled JspServletWrapper into the queue at first
- * execution of jsp.
+ * execution of jsp. Destroy any JSP the has been replaced in the queue.
*
* @param jsw Servlet wrapper for jsp.
* @return a ticket that can be pushed to front of queue at later execution times.
* */
public FastRemovalDequeue<JspServletWrapper>.Entry push(JspServletWrapper jsw) {
- synchronized (jspQueue) {
- return jspQueue.push(jsw);
+ FastRemovalDequeue<JspServletWrapper>.Entry entry = jspQueue.push(jsw);
+ JspServletWrapper replaced = entry.getReplaced();
+ if (replaced != null) {
+ unloadJspServletWrapper(replaced);
}
+ return entry;
}
/**
@@ -230,9 +238,7 @@ public final class JspRuntimeContext {
* @param ticket the ticket for the jsp.
* */
public void makeYoungest(FastRemovalDequeue<JspServletWrapper>.Entry ticket) {
- synchronized(jspQueue) {
- jspQueue.moveFirst(ticket);
- }
+ jspQueue.moveFirst(ticket);
}
/**
@@ -500,6 +506,13 @@ public final class JspRuntimeContext {
return new SecurityHolder(source, permissions);
}
+ private void unloadJspServletWrapper(JspServletWrapper jsw) {
+ removeWrapper(jsw.getJspUri());
+ synchronized(jsw) {
+ jsw.destroy();
+ }
+ }
+
/**
* Method used by background thread to check if any JSP's should be destroyed.
* If JSP's to be unloaded are found, they will be destroyed.
@@ -522,11 +535,8 @@ public final class JspRuntimeContext {
}
}
if (jsw != null) {
- removeWrapper(jsw.getJspUri());
- synchronized(jsw) {
- jsw.destroy();
- return true;
- }
+ unloadJspServletWrapper(jsw);
+ return true;
}
return false;
}
Modified: tomcat/trunk/java/org/apache/jasper/servlet/JspServletWrapper.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/servlet/JspServletWrapper.java?rev=1028935&r1=1028934&r2=1028935&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/servlet/JspServletWrapper.java (original)
+++ tomcat/trunk/java/org/apache/jasper/servlet/JspServletWrapper.java Fri Oct 29 22:44:52 2010
@@ -377,7 +377,6 @@ public class JspServletWrapper {
synchronized(this) {
if (ticket == null) {
ticket = ctxt.getRuntimeContext().push(this);
- ctxt.getRuntimeContext().unloadJsp();
} else {
ctxt.getRuntimeContext().makeYoungest(ticket);
}
Modified: tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java?rev=1028935&r1=1028934&r2=1028935&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java (original)
+++ tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java Fri Oct 29 22:44:52 2010
@@ -23,15 +23,18 @@ package org.apache.jasper.util;
* added to the collection with an Entry type, that is returned to the consumer.
* When removing an object from the list, the consumer provides this Entry object.
*
- * The Entry type is completely opaque to the consumer itself.
+ * The Entry type is nearly opaque to the consumer of the queue. The only public
+ * member is the getter for any object displaced when adding a new object to the
+ * queue. This can be used to destroy that object.
*
* The Entry object contains the links pointing to the neighbours in the doubly
* linked list, so that removal of an Entry does not need to search for it but
* instead can be done in constant time.
*
- * The implementation is not thread-safe. Full synchronisation has to be provided
- * externally. Invalidation of Entry objects during removal from the list is done
- * by setting their valid field to false. All public methods which take Entry
+ * The implementation is fully thread-safe.
+ *
+ * Invalidation of Entry objects during removal from the list is done
+ * by setting their "valid" field to false. All public methods which take Entry
* objects as arguments are NOP if the entry is no longer valid.
*
* A typical use of the FastRemovalDequeue is a list of entries in sorted order,
@@ -44,6 +47,8 @@ package org.apache.jasper.util;
*/
public class FastRemovalDequeue<T> {
+ /** Maximum size of the queue */
+ private final int maxSize;
/** First element of the queue. */
private Entry first;
/** Last element of the queue. */
@@ -52,7 +57,11 @@ public class FastRemovalDequeue<T> {
private int size;
/** Initialize empty queue. */
- public FastRemovalDequeue() {
+ public FastRemovalDequeue(int maxSize) {
+ if (maxSize <=1 ) {
+ maxSize = 2;
+ }
+ this.maxSize = maxSize;
first = null;
last = null;
size = 0;
@@ -65,7 +74,7 @@ public class FastRemovalDequeue<T> {
*
* @return the size of the list.
* */
- public int getSize() {
+ public synchronized int getSize() {
return size;
}
@@ -76,8 +85,11 @@ public class FastRemovalDequeue<T> {
* @param object the object to prepend to the start of the list.
* @return an entry for use when the object should be moved.
* */
- public Entry push(final T object) {
+ public synchronized Entry push(final T object) {
Entry entry = new Entry(object);
+ if (size >= maxSize) {
+ entry.setReplaced(pop());
+ }
if (first == null) {
first = last = entry;
} else {
@@ -97,8 +109,11 @@ public class FastRemovalDequeue<T> {
* @param object the object to append to the end of the list.
* @return an entry for use when the object should be moved.
* */
- public Entry unpop(final T object) {
+ public synchronized Entry unpop(final T object) {
Entry entry = new Entry(object);
+ if (size >= maxSize) {
+ entry.setReplaced(unpush());
+ }
if (first == null) {
first = last = entry;
} else {
@@ -116,16 +131,17 @@ public class FastRemovalDequeue<T> {
*
* @return the content of the first element of the list.
**/
- public T unpush() {
+ public synchronized T unpush() {
T content = null;
if (first != null) {
- content = first.getContent();
- first.setValid(false);
+ Entry element = first;
first = first.getNext();
+ content = element.getContent();
if (first != null) {
first.setPrevious(null);
}
size--;
+ element.setValid(false);
}
return content;
}
@@ -135,16 +151,17 @@ public class FastRemovalDequeue<T> {
*
* @return the content of the last element of the list.
**/
- public T pop() {
+ public synchronized T pop() {
T content = null;
if (last != null) {
- content = last.getContent();
- last.setValid(false);
+ Entry element = last;
last = last.getPrevious();
+ content = element.getContent();
if (last != null) {
last.setNext(null);
}
size--;
+ element.setValid(false);
}
return content;
}
@@ -152,7 +169,7 @@ public class FastRemovalDequeue<T> {
/**
* Removes any element of the list and returns its content.
**/
- public void remove(final Entry element) {
+ public synchronized void remove(final Entry element) {
if (!element.getValid()) {
return;
}
@@ -169,6 +186,7 @@ public class FastRemovalDequeue<T> {
first = next;
}
size--;
+ element.setValid(false);
}
/**
@@ -179,7 +197,7 @@ public class FastRemovalDequeue<T> {
*
* @param element the entry to move in front.
* */
- public void moveFirst(final Entry element) {
+ public synchronized void moveFirst(final Entry element) {
if (element.getValid() &&
element.getPrevious() != null) {
Entry prev = element.getPrevious();
@@ -205,7 +223,7 @@ public class FastRemovalDequeue<T> {
*
* @param element the entry to move to the back.
* */
- public void moveLast(final Entry element) {
+ public synchronized void moveLast(final Entry element) {
if (element.getValid() &&
element.getNext() != null) {
Entry next = element.getNext();
@@ -235,6 +253,8 @@ public class FastRemovalDequeue<T> {
private boolean valid = true;
/** The content this entry is valid for. */
private final T content;
+ /** Optional content that was displaced by this entry */
+ private T replaced = null;
/** Pointer to next element in queue. */
private Entry next = null;
/** Pointer to previous element in queue. */
@@ -256,6 +276,14 @@ public class FastRemovalDequeue<T> {
return content;
}
+ public final T getReplaced() {
+ return replaced;
+ }
+
+ private final void setReplaced(final T replaced) {
+ this.replaced = replaced;
+ }
+
private final Entry getNext() {
return next;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org