cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
jkf 2004/12/11 02:49:01 Modified:src/main/org/apache/tools/ant/taskdefs Tag: ANT_16_BRANCH Parallel.java Log: Sync Revision ChangesPath No revision No revision 1.24.2.6 +23 -5 ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java Index: Parallel.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java,v retrieving revision 1.24.2.5 retrieving revision 1.24.2.6 diff -u -r1.24.2.5 -r1.24.2.6 --- Parallel.java 1 Apr 2004 13:07:34 - 1.24.2.5 +++ Parallel.java 11 Dec 2004 10:49:01 - 1.24.2.6 @@ -56,9 +56,10 @@ /** * Add a nested task to execute parallel (asynchron). * p - * @param nestedTask Nested task to be executed in parallel + * @param nestedTask Nested task to be executed in parallel. + *must not be null. */ -public void addTask(Task nestedTask) throws BuildException { +public void addTask(Task nestedTask) { tasks.add(nestedTask); } } @@ -107,6 +108,7 @@ /** * Add a group of daemon threads + * @param daemonTasks The tasks to be executed as daemon. */ public void addDaemons(TaskList daemonTasks) { if (this.daemonTasks != null) { @@ -266,6 +268,14 @@ } synchronized (semaphore) { +// When we leave this block we can be sure all data is really +// stored in main memory before the new threads start, the new +// threads will for sure load the data from main memory. +// +// This probably is slightly paranoid. +} + +synchronized (semaphore) { // start any daemon threads if (daemons != null) { for (int i = 0; i daemons.length; ++i) { @@ -307,7 +317,7 @@ outer: while (threadNumber numTasks stillRunning) { for (int i = 0; i maxRunning; i++) { -if (running[i] == null || running[i].finished) { +if (running[i] == null || running[i].isFinished()) { running[i] = runnables[threadNumber++]; Thread thread = new Thread(group, running[i]); thread.start(); @@ -332,7 +342,7 @@ outer2: while (stillRunning) { for (int i = 0; i maxRunning; ++i) { -if (running[i] != null !running[i].finished) { +if (running[i] != null !running[i].isFinished()) { //System.out.println(Thread + i + is still alive ); // still running - wait for it try { @@ -397,7 +407,7 @@ private class TaskRunnable implements Runnable { private Throwable exception; private Task task; -boolean finished; +private boolean finished; /** * Construct a new TaskRunnable.p @@ -434,6 +444,14 @@ */ public Throwable getException() { return exception; +} + +/** + * Provides the indicator that the task has been finished. + * @return Returns true when the task is finished. + */ +boolean isFinished() { +return finished; } } - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
jkf 2004/12/09 14:17:24 Modified:src/main/org/apache/tools/ant/taskdefs Parallel.java Log: In bug 32566 someone asked about the thread safety requirements in Ant. This made me perform a quick check on the main flow of the Ant project from a threading perspective. The only cause for wich the tasks specified in the build file may be executed in another thread is the parallel task. The parallel task does not ensure all variables are stored in memory before the new threads start. Revision ChangesPath 1.30 +8 -0 ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java Index: Parallel.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- Parallel.java 1 Apr 2004 13:06:45 - 1.29 +++ Parallel.java 9 Dec 2004 22:17:24 - 1.30 @@ -266,6 +266,14 @@ } synchronized (semaphore) { +// When we leave this block we can be sure all data is really +// stored in main memory before the new threads start, the new +// threads will for sure load the data from main memory. +// +// This probably is slightly paranoid. +} + +synchronized (semaphore) { // start any daemon threads if (daemons != null) { for (int i = 0; i daemons.length; ++i) { - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
jkf 2004/12/09 15:06:47 Modified:src/main/org/apache/tools/ant/taskdefs Parallel.java Log: Checkstyle updates. (removed trailing spaces just added, updated javadoc, removed an undocumented BuildException which was neither thrown according to interface nor according to methods implementation.) Revision ChangesPath 1.31 +18 -8 ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java Index: Parallel.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- Parallel.java 9 Dec 2004 22:17:24 - 1.30 +++ Parallel.java 9 Dec 2004 23:06:47 - 1.31 @@ -56,9 +56,10 @@ /** * Add a nested task to execute parallel (asynchron). * p - * @param nestedTask Nested task to be executed in parallel + * @param nestedTask Nested task to be executed in parallel. + *must not be null. */ -public void addTask(Task nestedTask) throws BuildException { +public void addTask(Task nestedTask) { tasks.add(nestedTask); } } @@ -107,6 +108,7 @@ /** * Add a group of daemon threads + * @param daemonTasks The tasks to be executed as daemon. */ public void addDaemons(TaskList daemonTasks) { if (this.daemonTasks != null) { @@ -266,13 +268,13 @@ } synchronized (semaphore) { -// When we leave this block we can be sure all data is really -// stored in main memory before the new threads start, the new +// When we leave this block we can be sure all data is really +// stored in main memory before the new threads start, the new // threads will for sure load the data from main memory. // // This probably is slightly paranoid. } - + synchronized (semaphore) { // start any daemon threads if (daemons != null) { @@ -315,7 +317,7 @@ outer: while (threadNumber numTasks stillRunning) { for (int i = 0; i maxRunning; i++) { -if (running[i] == null || running[i].finished) { +if (running[i] == null || running[i].isFinished()) { running[i] = runnables[threadNumber++]; Thread thread = new Thread(group, running[i]); thread.start(); @@ -340,7 +342,7 @@ outer2: while (stillRunning) { for (int i = 0; i maxRunning; ++i) { -if (running[i] != null !running[i].finished) { +if (running[i] != null !running[i].isFinished()) { //System.out.println(Thread + i + is still alive ); // still running - wait for it try { @@ -405,7 +407,7 @@ private class TaskRunnable implements Runnable { private Throwable exception; private Task task; -boolean finished; +private boolean finished; /** * Construct a new TaskRunnable.p @@ -442,6 +444,14 @@ */ public Throwable getException() { return exception; +} + +/** + * Provides the indicator that the task has been finished. + * @return Returns true when the task is finished. + */ +boolean isFinished() { +return finished; } } - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
peterreilly2004/04/01 05:07:34 Modified:.Tag: ANT_16_BRANCH WHATSNEW src/main/org/apache/tools/ant/taskdefs Tag: ANT_16_BRANCH Parallel.java Log: sync with HEAD Revision ChangesPath No revision No revision 1.503.2.64 +2 -0 ant/WHATSNEW Index: WHATSNEW === RCS file: /home/cvs/ant/WHATSNEW,v retrieving revision 1.503.2.63 retrieving revision 1.503.2.64 diff -u -r1.503.2.63 -r1.503.2.64 --- WHATSNEW 31 Mar 2004 11:45:42 - 1.503.2.63 +++ WHATSNEW 1 Apr 2004 13:07:34 - 1.503.2.64 @@ -104,6 +104,8 @@ * wrong compare used in ProjectComponent for logging. Bugzilla Report 28070. +* failOnAny attribute for parallel was broken. Bugzilla Report 28122. + Other changes: -- No revision No revision 1.24.2.5 +3 -3 ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java Index: Parallel.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java,v retrieving revision 1.24.2.4 retrieving revision 1.24.2.5 diff -u -r1.24.2.4 -r1.24.2.5 --- Parallel.java 9 Mar 2004 17:01:34 - 1.24.2.4 +++ Parallel.java 1 Apr 2004 13:07:34 - 1.24.2.5 @@ -417,12 +417,12 @@ task.perform(); } catch (Throwable t) { exception = t; +if (failOnAny) { +stillRunning = false; +} } finally { synchronized (semaphore) { finished = true; -if (failOnAny) { -stillRunning = false; -} semaphore.notifyAll(); } } - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
conor 2003/07/25 04:02:53 Modified:.WHATSNEW docs/manual/CoreTasks parallel.html src/main/org/apache/tools/ant/taskdefs Parallel.java Log: Add daemons element to parallel to start daemon threads which continue to run after the parallel task has completed. Revision ChangesPath 1.468 +10 -2 ant/WHATSNEW Index: WHATSNEW === RCS file: /home/cvs/ant/WHATSNEW,v retrieving revision 1.467 retrieving revision 1.468 diff -u -w -u -r1.467 -r1.468 --- WHATSNEW 25 Jul 2003 10:06:31 - 1.467 +++ WHATSNEW 25 Jul 2003 11:02:52 - 1.468 @@ -515,6 +515,14 @@ * exec will now work on OpenVMS (please read the notes in exec's manual page). Bugzilla Report 21877. + +* parallel now supports a timeout which can be used to recover + from deadlocks, etc in the parallel threads. parallel also + now supports a daemons nested element. This can be used to + run tasks in daemon threads which the parallel task will not + wait for before completing. A new attribute failonany will cause + parallel to throw an exception if any thread fails without + waiting for all other threads to complete. Changes from Ant 1.5.2 to Ant 1.5.3 === 1.12 +19 -0 ant/docs/manual/CoreTasks/parallel.html Index: parallel.html === RCS file: /home/cvs/ant/docs/manual/CoreTasks/parallel.html,v retrieving revision 1.11 retrieving revision 1.12 diff -u -w -u -r1.11 -r1.12 --- parallel.html 24 Jul 2003 14:24:07 - 1.11 +++ parallel.html 25 Jul 2003 11:02:53 - 1.12 @@ -99,6 +99,25 @@ would occur. This is not a repalcement for Java Language level thread semantics and is best used for embarassingly parallel tasks./p + +h3Parameters specified as nested elements/h3 + +h4daemons/h4 +p +The parallel task supports a lt;daemonsgt; nested element. This is a list of tasks +which are to be run in parallel daemon threads. The parallel task will not wait for +these tasks to complete. Being daemon threads, however, they will not prevent Ant from +completing, whereupon the threads are terminated. Failures in daemon threads which +occur before the parallel task itself finishes will be reported and can cause +parallel to throw an exception. Failures which occur after parallel has completed are not +reported. +/p + +pDaemon tasks can be used, for example, to start test servers which might not be easily +terminated from Ant. By using lt;daemonsgt; such servers do not halt the build. +/p + + h3Examples/h3 pre lt;parallelgt; 1.23 +116 -54 ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java Index: Parallel.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java,v retrieving revision 1.22 retrieving revision 1.23 diff -u -w -u -r1.22 -r1.23 --- Parallel.java 25 Jul 2003 08:59:39 - 1.22 +++ Parallel.java 25 Jul 2003 11:02:53 - 1.23 @@ -56,6 +56,8 @@ import java.lang.reflect.Method; import java.util.Enumeration; import java.util.Vector; +import java.util.List; +import java.util.ArrayList; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Location; import org.apache.tools.ant.Task; @@ -86,6 +88,21 @@ public class Parallel extends Task implements TaskContainer { +/** Class which holds a list of tasks to execute */ +public static class TaskList implements TaskContainer { +/** Collection holding the nested tasks */ +private List tasks = new ArrayList(); + +/** + * Add a nested task to execute parallel (asynchron). + * p + * @param nestedTask Nested task to be executed in parallel + */ +public void addTask(Task nestedTask) throws BuildException { +tasks.add(nestedTask); +} +} + /** Collection holding the nested tasks */ private Vector nestedTasks = new Vector(); @@ -98,12 +115,13 @@ /** Total number of threads per processor to run. */ private int numThreadsPerProcessor = 0; +/** The timeout period in milliseconds */ private long timeout; /** Indicates threads are still running and new threads can be issued */ private volatile boolean stillRunning; -/** INdicates that the execution timedout */ +/** Indicates that the execution timedout */ private boolean timedOut; /** @@ -112,6 +130,31 @@ */ private boolean failOnAny; +/** The dameon task list if any */ +
cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
conor 2003/04/14 04:58:04 Modified:.check.xml src/main/org/apache/tools/ant IntrospectionHelper.java Project.java RuntimeConfigurable.java src/main/org/apache/tools/ant/filters BaseFilterReader.java EscapeUnicode.java StripLineComments.java src/main/org/apache/tools/ant/filters/util ChainReaderHelper.java src/main/org/apache/tools/ant/helper ProjectHelperImpl.java src/main/org/apache/tools/ant/taskdefs Parallel.java Log: style fixes Revision ChangesPath 1.5 +7 -7 ant/check.xml Index: check.xml === RCS file: /home/cvs/ant/check.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -w -u -r1.4 -r1.5 --- check.xml 8 Jan 2003 08:29:10 - 1.4 +++ check.xml 14 Apr 2003 11:58:02 - 1.5 @@ -6,10 +6,10 @@ target name=checkstyle taskdef name=checkstyle classname=com.puppycrawl.tools.checkstyle.CheckStyleTask/ -checkstyle - property key=checkstyle.header.file file=src/etc/RequiredHeader.txt/ - property key=checkstyle.header.ignoreline value=4/ - property key=checkstyle.javadoc.scope value=${javadoc.scope}/ +checkstyle headerFile=src/etc/RequiredHeader.txt +headerIgnoreLine=4 +allowProtected=true +javadocScope=${javadoc.scope} fileset dir=${java.dir} include name=${tocheck}/ /fileset 1.52 +1 -2 ant/src/main/org/apache/tools/ant/IntrospectionHelper.java Index: IntrospectionHelper.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v retrieving revision 1.51 retrieving revision 1.52 diff -u -w -u -r1.51 -r1.52 --- IntrospectionHelper.java 6 Apr 2003 09:30:56 - 1.51 +++ IntrospectionHelper.java 14 Apr 2003 11:58:03 - 1.52 @@ -436,8 +436,7 @@ DynamicConfigurator dc = (DynamicConfigurator) element; dc.setDynamicAttribute(attributeName, value); return; -} -else { +} else { String msg = getElementName(p, element) + doesn't support the \ + attributeName + \ attribute.; 1.134 +49 -34ant/src/main/org/apache/tools/ant/Project.java Index: Project.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/Project.java,v retrieving revision 1.133 retrieving revision 1.134 diff -u -w -u -r1.133 -r1.134 --- Project.java 3 Apr 2003 14:44:01 - 1.133 +++ Project.java 14 Apr 2003 11:58:03 - 1.134 @@ -903,8 +903,7 @@ oldLoader instanceof AntClassLoader newLoader instanceof AntClassLoader ((AntClassLoader) oldLoader).getClasspath() -.equals(((AntClassLoader) newLoader).getClasspath()) -) { +.equals(((AntClassLoader) newLoader).getClasspath())) { // same classname loaded from the same // classpath components logLevel = MSG_VERBOSE; @@ -2171,7 +2170,7 @@ // Should move to a separate public class - and have API to add // listeners, etc. private static class AntRefTable extends Hashtable { -Project project; +private Project project; public AntRefTable(Project project) { super(); this.project = project; @@ -2212,9 +2211,9 @@ } private static class AntTaskTable extends LazyHashtable { -Project project; -Properties props; -boolean tasks = false; +private Project project; +private Properties props; +private boolean tasks = false; public AntTaskTable(Project p, boolean tasks) { this.project = p; @@ -2226,26 +2225,33 @@ } protected void initAll() { -if (initAllDone ) return; +if (initAllDone) { +return; +} project.log(InitAll, Project.MSG_DEBUG); -if (props==null ) return; +if (props == null) { +return; +} Enumeration enum = props.propertyNames(); while (enum.hasMoreElements()) { String key = (String) enum.nextElement(); Class taskClass=getTask( key ); if (taskClass!=null )
cvs commit: ant/src/main/org/apache/tools/ant/taskdefs Parallel.java
conor 2003/04/07 07:47:02 Modified:src/main/org/apache/tools/ant/taskdefs Parallel.java Log: Remove duplication in Parallel Revision ChangesPath 1.16 +19 -82ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java Index: Parallel.java === RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Parallel.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -w -u -r1.15 -r1.16 --- Parallel.java 11 Feb 2003 11:26:44 - 1.15 +++ Parallel.java 7 Apr 2003 14:47:02 - 1.16 @@ -150,13 +150,12 @@ public void execute() throws BuildException { updateThreadCounts(); if (numThreads == 0) { -spinAllThreads(); -} else { -spinNumThreads(); +numThreads = nestedTasks.size(); } +spinThreads(); } -public void updateThreadCounts() { +private void updateThreadCounts() { if (numThreadsPerProcessor != 0) { int numProcessors = getNumProcessors(); if (numProcessors != 0) { @@ -168,18 +167,19 @@ /** * Spin up threadCount threads. */ -public void spinNumThreads() throws BuildException { -final int maxThreads = nestedTasks.size(); -Thread[] threads = new Thread[maxThreads]; -TaskThread[] taskThreads = new TaskThread[maxThreads]; +private void spinThreads() throws BuildException { +final int numTasks = nestedTasks.size(); +Thread[] threads = new Thread[numTasks]; +TaskRunnable[] runnables = new TaskRunnable[numTasks]; int threadNumber = 0; for (Enumeration e = nestedTasks.elements(); e.hasMoreElements(); threadNumber++) { Task nestedTask = (Task) e.nextElement(); ThreadGroup group = new ThreadGroup(parallel); -TaskThread taskThread = new TaskThread(threadNumber, nestedTask); -taskThreads[threadNumber] = taskThread; -threads[threadNumber] = new Thread(group, taskThread); +TaskRunnable taskRunnable += new TaskRunnable(threadNumber, nestedTask); +runnables[threadNumber] = taskRunnable; +threads[threadNumber] = new Thread(group, taskRunnable); } final int maxRunning = numThreads; @@ -188,7 +188,7 @@ // now run them in limited numbers... outer: -while (threadNumber maxThreads) { +while (threadNumber numTasks) { synchronized(semaphore) { for (int i = 0; i maxRunning; i++) { if (running[i] == null || !running[i].isAlive()) { @@ -225,8 +225,8 @@ int numExceptions = 0; Throwable firstException = null; Location firstLocation = Location.UNKNOWN_LOCATION;; -for (int i = 0; i maxThreads; ++i) { -Throwable t = taskThreads[i].getException(); +for (int i = 0; i numTasks; ++i) { +Throwable t = runnables[i].getException(); if (t != null) { numExceptions++; if (firstException == null) { @@ -253,71 +253,7 @@ } } -/** - * Spin up one thread per task. - */ -public void spinAllThreads() throws BuildException { -int numTasks = nestedTasks.size(); -Thread[] threads = new Thread[numTasks]; -TaskThread[] taskThreads = new TaskThread[numTasks]; -int threadNumber = 0; -for (Enumeration e = nestedTasks.elements(); e.hasMoreElements(); - threadNumber++) { -Task nestedTask = (Task) e.nextElement(); -ThreadGroup group = new ThreadGroup(parallel); -TaskThread taskThread = new TaskThread(threadNumber, nestedTask); -taskThreads[threadNumber] = taskThread; -threads[threadNumber] = new Thread(group, taskThread); -} - -// now start all threads -for (int i = 0; i threads.length; ++i) { -threads[i].start(); -} - -// now join to all the threads -for (int i = 0; i threads.length; ++i) { -try { -threads[i].join(); -} catch (InterruptedException ie) { -// who would interrupt me at a time like this? -} -} - -// now did any of the threads throw an exception -StringBuffer exceptionMessage = new StringBuffer(); -int numExceptions = 0; -Throwable firstException = null; -Location firstLocation = Location.UNKNOWN_LOCATION;; -for (int i = 0; i threads.length; ++i) { -