diff --git a/WHATSNEW b/WHATSNEW index 35b562a5b..d5479e389 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -157,6 +157,9 @@ Fixed bugs: * sometimes incorrectly flagged infinite recursions of filter tokens Bugzilla Report 44226. + + * Enhance performance of Project.fireMessageLoggedEvent + Bugzilla Report 45651. Other changes: -------------- diff --git a/contributors.xml b/contributors.xml index b76c1d252..6b216b172 100644 --- a/contributors.xml +++ b/contributors.xml @@ -417,6 +417,10 @@ Gerrit Riessen + + Gilles + Scokart + Glenn McAllister diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java index d588225d2..2be86930b 100644 --- a/src/main/org/apache/tools/ant/Project.java +++ b/src/main/org/apache/tools/ant/Project.java @@ -26,7 +26,6 @@ import java.lang.reflect.Modifier; import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; -import java.util.Iterator; import java.util.Properties; import java.util.Stack; import java.util.Vector; @@ -170,7 +169,7 @@ public class Project implements ResourceFactory { private final Object listenersLock = new Object(); /** List of listeners to notify of build events. */ - private Vector listeners = new Vector(); + private volatile BuildListener[] listeners = new BuildListener[0]; /** for each thread, record whether it is currently executing messageLogged */ @@ -387,12 +386,15 @@ public class Project implements ResourceFactory { public void addBuildListener(BuildListener listener) { synchronized (listenersLock) { // If the listeners already has this listener, do nothing - if (listeners.contains(listener)) { - return; + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] == listener) { + return; + } } // copy on write semantics - Vector newListeners = getBuildListeners(); - newListeners.addElement(listener); + BuildListener[] newListeners = new BuildListener[listeners.length + 1]; + System.arraycopy(listeners, 0, newListeners, 0, listeners.length); + newListeners[listeners.length] = listener; listeners = newListeners; } } @@ -407,19 +409,31 @@ public class Project implements ResourceFactory { public void removeBuildListener(BuildListener listener) { synchronized (listenersLock) { // copy on write semantics - Vector newListeners = getBuildListeners(); - newListeners.removeElement(listener); - listeners = newListeners; + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] == listener) { + BuildListener[] newListeners = new BuildListener[listeners.length - 1]; + System.arraycopy(listeners, 0, newListeners, 0, i); + System.arraycopy(listeners, i + 1, newListeners, i, listeners.length - i - 1); + listeners = newListeners; + break; + } + } } } /** - * Return a copy of the list of build listeners for the project. - * - * @return a list of build listeners for the project - */ + * Return a copy of the list of build listeners for the project. + * + * @return a list of build listeners for the project + */ public Vector getBuildListeners() { - return (Vector) listeners.clone(); + synchronized (listenersLock) { + Vector r = new Vector(listeners.length); + for (int i = 0; i < listeners.length; i++) { + r.add(listeners[i]); + } + return r; + } } /** @@ -1986,10 +2000,9 @@ public class Project implements ResourceFactory { */ public void fireBuildStarted() { BuildEvent event = new BuildEvent(this); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - BuildListener listener = (BuildListener) iter.next(); - listener.buildStarted(event); + BuildListener[] currListeners = listeners; + for (int i=0; i