Browse Source

Improved InterruptException handling, especially from Parallel task. Should also solve Pr 42924.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@576176 13f79535-47bb-0310-9956-ffa450edef68
master
Jacobus Martinus Kruithof 18 years ago
parent
commit
f1e7b4baf5
4 changed files with 91 additions and 51 deletions
  1. +66
    -32
      src/main/org/apache/tools/ant/taskdefs/Parallel.java
  2. +5
    -1
      src/main/org/apache/tools/ant/taskdefs/Redirector.java
  3. +14
    -13
      src/main/org/apache/tools/ant/taskdefs/WaitFor.java
  4. +6
    -5
      src/main/org/apache/tools/ant/util/Watchdog.java

+ 66
- 32
src/main/org/apache/tools/ant/taskdefs/Parallel.java View File

@@ -248,6 +248,7 @@ public class Parallel extends Task
TaskRunnable[] runnables = new TaskRunnable[numTasks];
stillRunning = true;
timedOut = false;
boolean interrupted = false;

int threadNumber = 0;
for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();
@@ -314,50 +315,48 @@ public class Parallel extends Task
timeoutThread.start();
}

// now find available running slots for the remaining threads
outer:
while (threadNumber < numTasks && stillRunning) {
for (int i = 0; i < maxRunning; i++) {
if (running[i] == null || running[i].isFinished()) {
running[i] = runnables[threadNumber++];
Thread thread = new Thread(group, running[i]);
thread.start();
// continue on outer while loop to get another
// available slot
continue outer;
try {
// now find available running slots for the remaining threads
outer: while (threadNumber < numTasks && stillRunning) {
for (int i = 0; i < maxRunning; i++) {
if (running[i] == null || running[i].isFinished()) {
running[i] = runnables[threadNumber++];
Thread thread = new Thread(group, running[i]);
thread.start();
// continue on outer while loop to get another
// available slot
continue outer;
}
}
}

// if we got here all slots in use, so sleep until
// something happens
try {
// if we got here all slots in use, so sleep until
// something happens
semaphore.wait();
} catch (InterruptedException ie) {
// doesn't java know interruptions are rude?
// just pretend it didn't happen and go about out business.
// sheesh!
}
}

// are all threads finished
outer2:
while (stillRunning) {
for (int i = 0; i < maxRunning; ++i) {
if (running[i] != null && !running[i].isFinished()) {
//System.out.println("Thread " + i + " is still alive ");
// still running - wait for it
try {
// are all threads finished
outer2: while (stillRunning) {
for (int i = 0; i < maxRunning; ++i) {
if (running[i] != null && !running[i].isFinished()) {
// System.out.println("Thread " + i + " is still
// alive ");
// still running - wait for it
semaphore.wait();
} catch (InterruptedException ie) {
// who would interrupt me at a time like this?
continue outer2;
}
continue outer2;
}
stillRunning = false;
}
stillRunning = false;
} catch (InterruptedException ie) {
interrupted = true;
}

killAll(running);
}

if (interrupted){
throw new BuildException("Parallel execution interrupted.");
}
if (timedOut) {
throw new BuildException("Parallel execution timed out");
}
@@ -382,6 +381,34 @@ public class Parallel extends Task
}
}

/**
* Doesn't do anything if all threads where already gone,
* else it tries to kill the threads 3 times.
* @param running The list of tasks that may currently be running.
*/
private void killAll(TaskRunnable[] running) {
boolean oneAlive;
int tries = 0;
do
{
oneAlive = false;
for (int i = 0; i < running.length; i++)
{
if (running[i] != null && ! running[i].isFinished())
{
running[i].interrupt();
Thread.yield();
oneAlive = true;
}
}
if (oneAlive)
{
tries++;
Thread.yield();
}
} while (oneAlive && tries < 100);
}

/**
* Determine the number of processors. Only effective on later VMs
*
@@ -409,6 +436,7 @@ public class Parallel extends Task
private Throwable exception;
private Task task;
private boolean finished;
private volatile Thread thread;

/**
* Construct a new TaskRunnable.<p>
@@ -425,6 +453,7 @@ public class Parallel extends Task
*/
public void run() {
try {
thread = Thread.currentThread();
task.perform();
} catch (Throwable t) {
exception = t;
@@ -454,6 +483,11 @@ public class Parallel extends Task
boolean isFinished() {
return finished;
}

void interrupt()
{
thread.interrupt();
}
}

}

+ 5
- 1
src/main/org/apache/tools/ant/taskdefs/Redirector.java View File

@@ -781,7 +781,11 @@ public class Redirector {
}
wait(1000);
} catch (InterruptedException eyeEx) {
// Ignore exception
Thread[] thread = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(thread);
for (int i = 0; i < thread.length && thread[i] != null; i++) {
thread[i].interrupt();
}
}
}



+ 14
- 13
src/main/org/apache/tools/ant/taskdefs/WaitFor.java View File

@@ -135,21 +135,22 @@ public class WaitFor extends ConditionBase {
long savedMaxWaitMillis = maxWaitMillis;
long savedCheckEveryMillis = checkEveryMillis;
try {
maxWaitMillis *= maxWaitMultiplier;
checkEveryMillis *= checkEveryMultiplier;
long start = System.currentTimeMillis();
long end = start + maxWaitMillis;
while (System.currentTimeMillis() < end) {
if (c.eval()) {
processSuccess();
return;
}
try {
try {
maxWaitMillis *= maxWaitMultiplier;
checkEveryMillis *= checkEveryMultiplier;
long start = System.currentTimeMillis();
long end = start + maxWaitMillis;
while (System.currentTimeMillis() < end) {
if (c.eval()) {
processSuccess();
return;
}
Thread.sleep(checkEveryMillis);
} catch (InterruptedException e) {
// ignore
}
} catch (InterruptedException e) {
log("Task " + getTaskName()
+ " interrupted, treating as timed out.");
}
processTimeout();
} finally {


+ 6
- 5
src/main/org/apache/tools/ant/util/Watchdog.java View File

@@ -110,13 +110,14 @@ public class Watchdog implements Runnable {
*/
public synchronized void run() {
final long until = System.currentTimeMillis() + timeout;
long now;
while (!stopped && until > (now = System.currentTimeMillis())) {
try {
long now = until - 1;
try {
while (!stopped && until > now) {
now = System.currentTimeMillis();
wait(until - now);
} catch (InterruptedException e) {
// Ignore exception
}
} catch (InterruptedException e) {
// Ignore exception
}
if (!stopped) {
fireTimeoutOccured();


Loading…
Cancel
Save