diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 7449a1f64..10e94b9a3 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -358,6 +358,7 @@ Thomas Quas
Tim Drury
Tim Fennell
Tim Stephenson
+Tim Whittington
Timoteo Ohara
Timothy Gerard Endres
Tom Ball
diff --git a/WHATSNEW b/WHATSNEW
index a2b1ff263..a7494f031 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -22,6 +22,9 @@ Fixed bugs:
made macrodef fail.
Bugzilla Report 55885.
+ * Ant 1.8 exec task changes have slowed exec to a crawl
+ Bugzilla Report 54128.
+
Other changes:
--------------
diff --git a/contributors.xml b/contributors.xml
index 68b144efe..c3d90b6c0 100644
--- a/contributors.xml
+++ b/contributors.xml
@@ -1435,6 +1435,10 @@
Tim
Fennell
+
+ Tim
+ Whittington
+
Timoteo
Ohara
diff --git a/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java b/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
index 2ccae1e74..42ba0f486 100644
--- a/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
@@ -185,10 +185,10 @@ public class PumpStreamHandler implements ExecuteStreamHandler {
return;
}
- t.join(JOIN_TIMEOUT);
if (s != null && !s.isFinished()) {
s.stop();
}
+ t.join(JOIN_TIMEOUT);
while ((s == null || !s.isFinished()) && t.isAlive()) {
t.interrupt();
t.join(JOIN_TIMEOUT);
diff --git a/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java b/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
index c4ad9914a..b47e47bfc 100644
--- a/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
+++ b/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
@@ -116,7 +116,6 @@ public class StreamPumper implements Runnable {
started = true;
}
finished = false;
- finish = false;
final byte[] buf = new byte[bufferSize];
@@ -130,13 +129,29 @@ public class StreamPumper implements Runnable {
}
length = is.read(buf);
- if (length <= 0 || finish || Thread.interrupted()) {
+ if (length <= 0 || Thread.interrupted()) {
break;
}
os.write(buf, 0, length);
if (autoflush) {
os.flush();
}
+ if (finish) {
+ break;
+ }
+ }
+ // On completion, drain any available data (which might be the first data available for quick executions)
+ if (finish) {
+ while((length = is.available()) > 0) {
+ if (Thread.interrupted()) {
+ break;
+ }
+ length = is.read(buf, 0, Math.min(length, buf.length));
+ if (length <= 0) {
+ break;
+ }
+ os.write(buf, 0, length);
+ }
}
os.flush();
} catch (InterruptedException ie) {
@@ -150,6 +165,7 @@ public class StreamPumper implements Runnable {
FileUtils.close(os);
}
finished = true;
+ finish = false;
synchronized (this) {
notifyAll();
}