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 <[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 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: [email protected]
For additional commands, e-mail: [email protected]