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: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org