2
* The Apache Software License, Version 1.1
4
* Copyright (c) 2001 The Apache Software Foundation. All rights
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in
16
* the documentation and/or other materials provided with the
19
* 3. The end-user documentation included with the redistribution, if
20
* any, must include the following acknowlegement:
21
* "This product includes software developed by the
22
* Apache Software Foundation (http://www.apache.org/)."
23
* Alternately, this acknowlegement may appear in the software itself,
24
* if and wherever such third-party acknowlegements normally appear.
26
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
27
* Foundation" must not be used to endorse or promote products derived
28
* from this software without prior written permission. For written
29
* permission, please contact apache@apache.org.
31
* 5. Products derived from this software may not be called "Apache"
32
* nor may "Apache" appear in their names without prior written
33
* permission of the Apache Group.
35
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
* ====================================================================
49
* This software consists of voluntary contributions made by many
50
* individuals on behalf of the Apache Software Foundation. For more
51
* information on the Apache Software Foundation, please see
52
* <http://www.apache.org/>.
54
package org.apache.tools.ant.taskdefs;
56
import org.apache.tools.ant.*;
57
import org.apache.tools.ant.types.*;
60
import java.lang.RuntimeException;
63
* Implements a multi threaded task execution.
65
* @author Thomas Christen <a href="mailto:chr@active.ch">chr@active.ch</a>
66
* @author <a href="mailto:conor@apache.org">Conor MacNeill </a>
68
public class Parallel extends Task
69
implements TaskContainer {
71
/** Collection holding the nested tasks */
72
private Vector nestedTasks = new Vector();
76
* Add a nested task to execute parallel (asynchron).
78
* @param nestedTask Nested task to be executed in parallel
80
public void addTask(Task nestedTask) throws BuildException {
81
nestedTasks.addElement(nestedTask);
85
* Block execution until the specified time or for a
86
* specified amount of milliseconds and if defined,
87
* execute the wait status.
89
public void execute() throws BuildException {
90
TaskThread[] threads = new TaskThread[nestedTasks.size()];
92
for (Enumeration e = nestedTasks.elements(); e.hasMoreElements(); threadNumber++) {
93
Task nestedTask = (Task)e.nextElement();
94
threads[threadNumber] = new TaskThread(threadNumber, nestedTask);
97
// now start all threads
98
for (int i = 0; i < threads.length; ++i) {
102
// now join to all the threads
103
for (int i = 0; i < threads.length; ++i) {
107
catch (InterruptedException ie) {
108
// who would interrupt me at a time like this?
112
// now did any of the threads throw an exception
113
StringBuffer exceptionMessage = new StringBuffer();
114
String lSep = System.getProperty("line.separator");
115
int numExceptions = 0;
116
Throwable firstException = null;
117
Location firstLocation = Location.UNKNOWN_LOCATION;;
118
for (int i = 0; i < threads.length; ++i) {
119
Throwable t = threads[i].getException();
122
if (firstException == null) {
125
if (t instanceof BuildException &&
126
firstLocation == Location.UNKNOWN_LOCATION) {
127
firstLocation = ((BuildException)t).getLocation();
129
exceptionMessage.append(lSep);
130
exceptionMessage.append(t.getMessage());
134
if (numExceptions == 1) {
135
if (firstException instanceof BuildException) {
136
throw (BuildException)firstException;
139
throw new BuildException(firstException);
142
else if (numExceptions > 1) {
143
throw new BuildException(exceptionMessage.toString(), firstLocation);
147
class TaskThread extends Thread {
148
private Throwable exception;
150
private int taskNumber;
153
* Construct a new TaskThread<p>
155
* @param task the Task to be executed in a seperate thread
157
TaskThread(int taskNumber, Task task) {
159
this.taskNumber = taskNumber;
163
* Executes the task within a thread and takes care about
164
* Exceptions raised within the task.
170
catch (Throwable t) {
175
public Throwable getException() {