This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push: new 2eeb45f80e Refactor to use CopyOnWriteArrayList rather than hand-crafted equivalent 2eeb45f80e is described below commit 2eeb45f80e17b95f5986e0be2cc29bd6fd165801 Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Aug 10 15:25:47 2023 +0100 Refactor to use CopyOnWriteArrayList rather than hand-crafted equivalent In response to a concurrency issue raised by Coverity --- java/org/apache/catalina/core/StandardContext.java | 62 +++++----------------- 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java index 5f9cbc1e89..6d76f8987c 100644 --- a/java/org/apache/catalina/core/StandardContext.java +++ b/java/org/apache/catalina/core/StandardContext.java @@ -201,12 +201,10 @@ public class StandardContext extends ContainerBase implements Context, Notificat /** - * The set of application listener class names configured for this application, in the order they were encountered - * in the resulting merged web.xml file. + * The list of unique application listener class names configured for this application, in the order they were + * encountered in the resulting merged web.xml file. */ - private String applicationListeners[] = new String[0]; - - private final Object applicationListenersLock = new Object(); + private CopyOnWriteArrayList<String> applicationListeners = new CopyOnWriteArrayList<>(); /** * The set of application listeners that are required to have limited access to ServletContext methods. See Servlet @@ -2722,21 +2720,11 @@ public class StandardContext extends ContainerBase implements Context, Notificat */ @Override public void addApplicationListener(String listener) { - - synchronized (applicationListenersLock) { - String results[] = new String[applicationListeners.length + 1]; - for (int i = 0; i < applicationListeners.length; i++) { - if (listener.equals(applicationListeners[i])) { - log.info(sm.getString("standardContext.duplicateListener", listener)); - return; - } - results[i] = applicationListeners[i]; - } - results[applicationListeners.length] = listener; - applicationListeners = results; + if (applicationListeners.addIfAbsent(listener)) { + fireContainerEvent("addApplicationListener", listener); + } else { + log.info(sm.getString("standardContext.duplicateListener", listener)); } - fireContainerEvent("addApplicationListener", listener); - } @@ -3225,7 +3213,7 @@ public class StandardContext extends ContainerBase implements Context, Notificat */ @Override public String[] findApplicationListeners() { - return applicationListeners; + return applicationListeners.toArray(new String[0]); } @@ -3576,36 +3564,10 @@ public class StandardContext extends ContainerBase implements Context, Notificat */ @Override public void removeApplicationListener(String listener) { - - synchronized (applicationListenersLock) { - - // Make sure this listener is currently present - int n = -1; - for (int i = 0; i < applicationListeners.length; i++) { - if (applicationListeners[i].equals(listener)) { - n = i; - break; - } - } - if (n < 0) { - return; - } - - // Remove the specified listener - int j = 0; - String results[] = new String[applicationListeners.length - 1]; - for (int i = 0; i < applicationListeners.length; i++) { - if (i != n) { - results[j++] = applicationListeners[i]; - } - } - applicationListeners = results; - + if (applicationListeners.remove(listener)) { + // Inform interested listeners if the specified listener was present and has been removed + fireContainerEvent("removeApplicationListener", listener); } - - // Inform interested listeners - fireContainerEvent("removeApplicationListener", listener); - } @@ -5305,7 +5267,7 @@ public class StandardContext extends ContainerBase implements Context, Notificat // Bugzilla 32867 distributable = false; - applicationListeners = new String[0]; + applicationListeners.clear(); 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