Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/dr/app/beast/BeastMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.logging.*;
Expand Down Expand Up @@ -80,11 +79,8 @@ public BeastConsoleApp(String nameString, String titleString, String aboutString
}

public void doStop() {
Iterator iter = parser.getThreads();
while (iter.hasNext()) {
Thread thread = (Thread) iter.next();
//noinspection removal
thread.stop(); // http://java.sun.com/j2se/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
if (parser != null) {
parser.interruptThreads();
}
}

Expand Down Expand Up @@ -1039,5 +1035,3 @@ public void uncaughtException(Thread t, Throwable e) {
}
}
}


88 changes: 79 additions & 9 deletions src/dr/xml/XMLParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@
import org.xml.sax.helpers.DefaultHandler;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Logger;

public class XMLParser {

private static final Logger LOGGER = Logger.getLogger(XMLParser.class.getName());

public static final String ID = XMLObject.ID;
public static final String IDREF = "idref";
public static final String CONCURRENT = "concurrent";
Expand Down Expand Up @@ -105,7 +110,24 @@ public Iterator getParsers() {
}

public Iterator getThreads() {
return threads.iterator();
synchronized (threadLock) {
return new ArrayList<Thread>(threads).iterator();
}
}

public void interruptThreads() {
List<Thread> currentThreads;
synchronized (threadLock) {
if (interruptRequested) {
return;
}
interruptRequested = true;
currentThreads = new ArrayList<Thread>(threads);
}
for (Thread thread : currentThreads) {
requestThreadStop(thread);
thread.interrupt();
}
}

public void storeObject(String name, Object object) {
Expand Down Expand Up @@ -370,9 +392,13 @@ private Object convert(Element e, Class target, XMLObject parent, boolean run, b
for (int i = 0; i < xo.getChildCount(); i++) {
Object child = xo.getChild(i);
if (child instanceof Runnable) {
Thread thread = new Thread((Runnable) child);
Runnable runnable = (Runnable) child;
Thread thread = new Thread(runnable);
thread.start();
threads.add(thread);
synchronized (threadLock) {
threads.add(thread);
threadTasks.put(thread, runnable);
}
} else throw new XMLParseException("Concurrent element children must be runnable!");
}
concurrent = false;
Expand All @@ -387,13 +413,21 @@ private Object convert(Element e, Class target, XMLObject parent, boolean run, b
if (obj instanceof Spawnable && !((Spawnable) obj).getSpawnable()) {
((Spawnable) obj).run();
} else {
Thread thread = new Thread((Runnable) obj);
Runnable runnable = (Runnable) obj;
Thread thread = new Thread(runnable);
thread.start();
threads.add(thread);
synchronized (threadLock) {
threads.add(thread);
threadTasks.put(thread, runnable);
}
waitForThread(thread);
}
}
threads.removeAllElements();
synchronized (threadLock) {
threadTasks.clear();
threads.removeAllElements();
interruptRequested = false;
}
}

return xo;
Expand Down Expand Up @@ -551,9 +585,44 @@ private void waitForThread(Thread thread) {
try {
thread.join();
} catch (InterruptedException ie) {
// DO NOTHING
// Preserve interrupt status for callers that manage parser shutdown.
Thread.currentThread().interrupt();
requestThreadStop(thread);
removeThreadTracking(thread);
return;
}
}
removeThreadTracking(thread);
}

private void requestThreadStop(Thread thread) {
Runnable runnable;
synchronized (threadLock) {
runnable = threadTasks.get(thread);
}
if (runnable == null) {
return;
}
try {
Method method = runnable.getClass().getMethod("pleaseStop");
method.invoke(runnable);
} catch (NoSuchMethodException ignored) {
// Expected: runnable does not implement pleaseStop().
} catch (IllegalAccessException e) {
LOGGER.warning("Error while accessing pleaseStop() on " +
runnable.getClass().getName() + ": " + e.getMessage());
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
LOGGER.warning("Error while invoking pleaseStop() on " +
runnable.getClass().getName() + ": " + (cause == null ? e.getMessage() : cause.getMessage()));
}
}

private void removeThreadTracking(Thread thread) {
synchronized (threadLock) {
threadTasks.remove(thread);
threads.remove(thread);
}
}

// //anonymous object store class
Expand Down Expand Up @@ -612,7 +681,10 @@ public void addCitable(Citable citable) {
private final Map<String, XMLObjectParser> parserStore = new TreeMap<String, XMLObjectParser>(new ParserComparator());
private final Map<String, XMLObject> objectStore = new LinkedHashMap<String, XMLObject>();
private final Map<Pair<String, String>, List<Citation>> citationStore = new LinkedHashMap<Pair<String, String>, List<Citation>>();
private final Map<Thread, Runnable> threadTasks = new HashMap<Thread, Runnable>();
private final Object threadLock = new Object();
private boolean concurrent = false;
private boolean interruptRequested = false;
private XMLObject root = null;

private boolean verbose = false;
Expand Down Expand Up @@ -656,5 +728,3 @@ public int compare(String o1, String o2) {
}

}