Author: markt
Date: Mon Sep 14 18:30:22 2015
New Revision: 1703024
URL: http://svn.apache.org/r1703024
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58373
Fix rare data race with the application event listeners for StandardContext
Modified:
tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1703024&r1=1703023&r2=1703024&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Mon Sep 14
18:30:22 2015
@@ -42,6 +42,7 @@ import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
@@ -217,12 +218,11 @@ public class StandardContext extends Con
private final Set<Object> noPluggabilityListeners = new HashSet<>();
/**
- * The set of instantiated application event listener objects. Note that
+ * The list of instantiated application event listener objects. Note that
* SCIs and other code may use the pluggability APIs to add listener
* instances directly to this list before the application starts.
*/
- private Object applicationEventListenersObjects[] =
- new Object[0];
+ private List<Object> applicationEventListenersList = new
CopyOnWriteArrayList<>();
/**
@@ -1150,26 +1150,34 @@ public class StandardContext extends Con
@Override
public Object[] getApplicationEventListeners() {
- return (applicationEventListenersObjects);
+ return applicationEventListenersList.toArray();
}
+ /**
+ * {@inheritDoc}
+ *
+ * Note that this implementation is not thread safe. If two threads call
+ * this method concurrently, the result may be either set of listeners or a
+ * the union of both.
+ */
@Override
public void setApplicationEventListeners(Object listeners[]) {
- applicationEventListenersObjects = listeners;
+ applicationEventListenersList.clear();
+ if (listeners != null && listeners.length > 0) {
+ applicationEventListenersList.addAll(Arrays.asList(listeners));
+ }
}
/**
* Add a listener to the end of the list of initialized application event
* listeners.
+ *
+ * @param listener The listener to add
*/
public void addApplicationEventListener(Object listener) {
- int len = applicationEventListenersObjects.length;
- Object[] newListeners = Arrays.copyOf(applicationEventListenersObjects,
- len + 1);
- newListeners[len] = listener;
- applicationEventListenersObjects = newListeners;
+ applicationEventListenersList.add(listener);
}
@@ -5578,7 +5586,7 @@ public class StandardContext extends Con
distributable = false;
applicationListeners = new String[0];
- applicationEventListenersObjects = new Object[0];
+ applicationEventListenersList.clear();
applicationLifecycleListenersObjects = new Object[0];
jspConfigDescriptor = null;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]