Browse Source

Thread safety fix in case a macrodef/presetdef is executed in parallel to other type related tasks (like TypeFound conditions or starting a subproject)

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

+ 29
- 17
src/main/org/apache/tools/ant/ComponentHelper.java View File

@@ -65,19 +65,19 @@ public class ComponentHelper {
private AntTypeTable antTypeTable; private AntTypeTable antTypeTable;


/** Map of tasks generated from antTypeTable */ /** Map of tasks generated from antTypeTable */
private Hashtable taskClassDefinitions = new Hashtable();
private final Hashtable taskClassDefinitions = new Hashtable();


/** flag to rebuild taskClassDefinitions */ /** flag to rebuild taskClassDefinitions */
private boolean rebuildTaskClassDefinitions = true; private boolean rebuildTaskClassDefinitions = true;


/** Map of types generated from antTypeTable */ /** Map of types generated from antTypeTable */
private Hashtable typeClassDefinitions = new Hashtable();
private final Hashtable typeClassDefinitions = new Hashtable();


/** flag to rebuild typeClassDefinitions */ /** flag to rebuild typeClassDefinitions */
private boolean rebuildTypeClassDefinitions = true; private boolean rebuildTypeClassDefinitions = true;


/** Set of namespaces that have been checked for antlibs */ /** Set of namespaces that have been checked for antlibs */
private Set checkedNamespaces = new HashSet();
private final HashSet checkedNamespaces = new HashSet();


/** /**
* Stack of antlib contexts used to resolve definitions while * Stack of antlib contexts used to resolve definitions while
@@ -192,6 +192,13 @@ public class ComponentHelper {
antTypeTable = new AntTypeTable(project); antTypeTable = new AntTypeTable(project);
} }


/**
* @return A copy of the CheckedNamespace.
*/
private synchronized Set getCheckedNamespace() {
return (Set) checkedNamespaces.clone();
}
/** /**
* Used with creating child projects. Each child * Used with creating child projects. Each child
* project inherits the component definitions * project inherits the component definitions
@@ -200,14 +207,17 @@ public class ComponentHelper {
*/ */
public void initSubProject(ComponentHelper helper) { public void initSubProject(ComponentHelper helper) {
// add the types of the parent project // add the types of the parent project
AntTypeTable typeTable = helper.antTypeTable;
for (Iterator i = typeTable.values().iterator(); i.hasNext();) {
AntTypeDefinition def = (AntTypeDefinition) i.next();
antTypeTable.put(def.getName(), def);
AntTypeTable typeTable = (AntTypeTable) helper.antTypeTable.clone();
synchronized (antTypeTable) {
for (Iterator i = typeTable.values().iterator(); i.hasNext();) {
AntTypeDefinition def = (AntTypeDefinition) i.next();
antTypeTable.put(def.getName(), def);
}
} }
// add the parsed namespaces of the parent project // add the parsed namespaces of the parent project
for (Iterator i = helper.checkedNamespaces.iterator(); i.hasNext();) {
checkedNamespaces.add(i.next());
Set inheritedCheckedNamespace = helper.getCheckedNamespace();
synchronized (this) {
checkedNamespaces.addAll(inheritedCheckedNamespace);
} }


// Add the restricted definitions // Add the restricted definitions
@@ -581,12 +591,14 @@ public class ComponentHelper {
// but this is for logging only... // but this is for logging only...
Class elementClass = o.getClass(); Class elementClass = o.getClass();
String elementClassname = elementClass.getName(); String elementClassname = elementClass.getName();
for (Iterator i = antTypeTable.values().iterator(); i.hasNext();) {
AntTypeDefinition def = (AntTypeDefinition) i.next();
if (elementClassname.equals(def.getClassName())
&& (elementClass == def.getExposedClass(project))) {
String name = def.getName();
return brief ? name : "The <" + name + "> type";
synchronized (antTypeTable) {
for (Iterator i = antTypeTable.values().iterator(); i.hasNext();) {
AntTypeDefinition def = (AntTypeDefinition) i.next();
if (elementClassname.equals(def.getClassName())
&& (elementClass == def.getExposedClass(project))) {
String name = def.getName();
return brief ? name : "The <" + name + "> type";
}
} }
} }
return getUnmappedElementName(o.getClass(), brief); return getUnmappedElementName(o.getClass(), brief);
@@ -1071,7 +1083,7 @@ public class ComponentHelper {
return def == null ? null : def.getExposedClass(project); return def == null ? null : def.getExposedClass(project);
} }


public boolean contains(Object clazz) {
public synchronized boolean contains(Object clazz) {
boolean found = false; boolean found = false;
if (clazz instanceof Class) { if (clazz instanceof Class) {
for (Iterator i = values().iterator(); i.hasNext() && !found;) { for (Iterator i = values().iterator(); i.hasNext() && !found;) {
@@ -1091,7 +1103,7 @@ public class ComponentHelper {
* @param prefix prefix to match off * @param prefix prefix to match off
* @return the (possibly empty) list of definitions * @return the (possibly empty) list of definitions
*/ */
public List/*<AntTypeDefinition>*/ findMatches(String prefix) {
public synchronized List/*<AntTypeDefinition>*/ findMatches(String prefix) {
ArrayList matches = new ArrayList(); ArrayList matches = new ArrayList();
for (Iterator i = values().iterator(); i.hasNext();) { for (Iterator i = values().iterator(); i.hasNext();) {
AntTypeDefinition def = (AntTypeDefinition) (i.next()); AntTypeDefinition def = (AntTypeDefinition) (i.next());


Loading…
Cancel
Save