Browse Source

Thread safety fix (list of delegates were modified and copied concurrently without common lock). The hashtable is thread safe and not published outside the class, so no need to copy it (synchronize non atomic modification is enought). However, the list contained in the delegates hashtable are published and should thus be copied. I put the copy in the add method so that the getDelegates doesn't need to be synchronized.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@687325 13f79535-47bb-0310-9956-ffa450edef68
master
Scokart Gilles 17 years ago
parent
commit
4c4ad3483d
1 changed files with 11 additions and 13 deletions
  1. +11
    -13
      src/main/org/apache/tools/ant/PropertyHelper.java

+ 11
- 13
src/main/org/apache/tools/ant/PropertyHelper.java View File

@@ -177,7 +177,7 @@ public class PropertyHelper implements GetProperty {

private Project project;
private PropertyHelper next;
private volatile Hashtable delegates = new Hashtable();
private Hashtable delegates = new Hashtable();

/** Project properties map (usually String to String). */
private Hashtable properties = new Hashtable();
@@ -924,35 +924,33 @@ public class PropertyHelper implements GetProperty {
* @since Ant 1.8
*/
public void add(Delegate delegate) {
synchronized (Delegate.class) {
Hashtable newDelegates = (Hashtable) delegates.clone();
synchronized (delegates) {
for (Iterator iter = getDelegateInterfaces(delegate).iterator(); iter.hasNext();) {
Object key = iter.next();
List list = (List) newDelegates.get(key);
List list = (List) delegates.get(key);
if (list == null) {
list = new ArrayList();
newDelegates.put(key, list);
}
if (list.contains(delegate)) {
} else {
list = new ArrayList(list);
list.remove(delegate);
}
list.add(0, delegate);
delegates.put(key, Collections.unmodifiableList(list));
}
delegates = newDelegates;
}
}

/**
* Get the Collection of delegates of the specified type.
* @param type delegate type.
*
* @param type
* delegate type.
* @return Collection.
* @since Ant 1.8
*/
protected List getDelegates(Class type) {
Hashtable curDelegates = delegates;
return curDelegates.containsKey(type)
? (List) new ArrayList((List) curDelegates.get(type))
: Collections.EMPTY_LIST;
List r = (List) delegates.get(type);
return r == null ? Collections.EMPTY_LIST : r;
}

/**


Loading…
Cancel
Save