This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 030e748852 Refactor to use CopyOnWriteArrayList rather than
hand-crafted equivalent
030e748852 is described below
commit 030e748852cd7018929cf87cbe1021f97ff0abed
Author: Mark Thomas <[email protected]>
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 d038e18460..d621fe7d45 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -202,12 +202,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
@@ -2682,21 +2680,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);
-
}
@@ -3198,7 +3186,7 @@ public class StandardContext extends ContainerBase
implements Context, Notificat
*/
@Override
public String[] findApplicationListeners() {
- return applicationListeners;
+ return applicationListeners.toArray(new String[0]);
}
@@ -3611,36 +3599,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);
-
}
@@ -5359,7 +5321,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: [email protected]
For additional commands, e-mail: [email protected]