Repository: ant
Updated Branches:
  refs/heads/master 33d20f436 -> 1388e372a


make LocalPropertyStack thread-safe

https://issues.apache.org/bugzilla/show_bug.cgi?id=55074


Project: http://git-wip-us.apache.org/repos/asf/ant/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant/commit/1388e372
Tree: http://git-wip-us.apache.org/repos/asf/ant/tree/1388e372
Diff: http://git-wip-us.apache.org/repos/asf/ant/diff/1388e372

Branch: refs/heads/master
Commit: 1388e372a9eb6cc6c463fbda928a10afd17b6d0a
Parents: 33d20f4
Author: Stefan Bodewig <[email protected]>
Authored: Wed Feb 11 14:26:00 2015 +0100
Committer: Stefan Bodewig <[email protected]>
Committed: Wed Feb 11 14:26:00 2015 +0100

----------------------------------------------------------------------
 WHATSNEW                                        |  4 ++
 .../tools/ant/property/LocalPropertyStack.java  | 45 +++++++++++++-------
 2 files changed, 33 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant/blob/1388e372/WHATSNEW
----------------------------------------------------------------------
diff --git a/WHATSNEW b/WHATSNEW
index b25e43a..1cdbd44 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -77,6 +77,10 @@ Fixed bugs:
  * complete-ant-cmd.pl now also completes tasks without a description.
    Bugzilla Report 57542
 
+ * LocalPropertyStack could run into ConcurrentModificationException
+   when tasks spawned new child threads that accessed the properties.
+   Bugzilla Report 55074
+
 Other changes:
 --------------
 

http://git-wip-us.apache.org/repos/asf/ant/blob/1388e372/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/property/LocalPropertyStack.java 
b/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
index cced579..482f28c 100644
--- a/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
+++ b/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
@@ -17,10 +17,9 @@
  */
 package org.apache.tools.ant.property;
 
-
-import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.tools.ant.PropertyHelper;
 
@@ -31,6 +30,7 @@ import org.apache.tools.ant.PropertyHelper;
  */
 public class LocalPropertyStack {
     private final LinkedList<Map<String, Object>> stack = new 
LinkedList<Map<String, Object>>();
+    private final Object LOCK = new Object();
 
     // --------------------------------------------------
     //
@@ -43,8 +43,11 @@ public class LocalPropertyStack {
      * @param property the name of the local property.
      */
     public void addLocal(String property) {
-        if (!stack.isEmpty()) {
-            stack.getFirst().put(property, NullReturn.NULL);
+        synchronized (LOCK) {
+            Map<String, Object> map = stack.peek();
+            if (map != null) {
+                map.put(property, NullReturn.NULL);
+            }
         }
     }
 
@@ -52,14 +55,18 @@ public class LocalPropertyStack {
      * Enter the local scope.
      */
     public void enterScope() {
-        stack.addFirst(new HashMap<String, Object>());
+        synchronized (LOCK) {
+            stack.addFirst(new ConcurrentHashMap<String, Object>());
+        }
     }
 
     /**
      * Exit the local scope.
      */
     public void exitScope() {
-        stack.removeFirst().clear();
+        synchronized (LOCK) {
+            stack.removeFirst().clear();
+        }
     }
 
     // --------------------------------------------------
@@ -73,9 +80,11 @@ public class LocalPropertyStack {
      * @return a copy.
      */
     public LocalPropertyStack copy() {
-        LocalPropertyStack ret = new LocalPropertyStack();
-        ret.stack.addAll(stack);
-        return ret;
+        synchronized (LOCK) {
+            LocalPropertyStack ret = new LocalPropertyStack();
+            ret.stack.addAll(stack);
+            return ret;
+        }
     }
 
     // --------------------------------------------------
@@ -91,10 +100,12 @@ public class LocalPropertyStack {
      * @return Object value.
      */
     public Object evaluate(String property, PropertyHelper helper) {
-        for (Map<String, Object> map : stack) {
-            Object ret = map.get(property);
-            if (ret != null) {
-                return ret;
+        synchronized (LOCK) {
+            for (Map<String, Object> map : stack) {
+                Object ret = map.get(property);
+                if (ret != null) {
+                    return ret;
+                }
             }
         }
         return null;
@@ -137,9 +148,11 @@ public class LocalPropertyStack {
     }
 
     private Map<String, Object> getMapForProperty(String property) {
-        for (Map<String, Object> map : stack) {
-            if (map.get(property) != null) {
-                return map;
+        synchronized (LOCK) {
+            for (Map<String, Object> map : stack) {
+                if (map.get(property) != null) {
+                    return map;
+                }
             }
         }
         return null;

Reply via email to