aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test-extensions/net
diff options
context:
space:
mode:
authorAdam Domurad <[email protected]>2013-04-25 17:05:31 -0400
committerAdam Domurad <[email protected]>2013-04-25 17:05:31 -0400
commit6d5754626525233d2bda2e388632f8b4476484c9 (patch)
tree51f9d21ddf410be3415509ddfd2a7a6f0941b9de /tests/test-extensions/net
parent61ca0a975341f40fbbb46379b10fbf77f0bf3d95 (diff)
Add accidentally not included files
Diffstat (limited to 'tests/test-extensions/net')
-rw-r--r--tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java102
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java b/tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java
new file mode 100644
index 0000000..f3f1716
--- /dev/null
+++ b/tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java
@@ -0,0 +1,102 @@
+package net.sourceforge.jnlp;
+
+import java.util.concurrent.Callable;
+
+/**
+ * A call that runs on a separate thread, with an optional timeout. It takes a runnable and allows
+ * joining.
+ *
+ * On join, throws any exceptions that occurred within the call, or a TimeOutException if
+ * it did not finish. Returns the value from the call.
+ */
+public class AsyncCall<T> {
+ static public class TimeOutException extends RuntimeException {
+ public TimeOutException() {
+ super("Call did not finish within the allocated time.");
+ }
+ }
+
+ private Thread handler;
+ private Callable<T> callable;
+ private long timeout;
+ private T callResult;
+
+ /* Captures exception from async call */
+ private Exception asyncException = null;
+
+ /* Create an AsyncCall with a given time-out */
+ public AsyncCall(Callable<T> callable, long timeout) {
+ this.callable = callable;
+ this.timeout = timeout;
+ this.handler = new HandlerThread();
+ }
+
+ /* Create an AsyncCall with (effectively) no time-out */
+ public AsyncCall(Callable<T> call) {
+ this(call, Long.MAX_VALUE);
+ }
+
+ /* Chains construction + start for convenience */
+ public static <T> AsyncCall<T> startWithTimeOut(Callable<T> callable, long timeout) {
+ AsyncCall<T> asyncCall = new AsyncCall<T>(callable, timeout);
+ asyncCall.start();
+ return asyncCall;
+ }
+
+ /* Chains construction + start for convenience */
+ public static <T> AsyncCall<T> startWithTimeOut(Callable<T> callable) {
+ return startWithTimeOut(callable, 1000); // Default timeout of 1 second
+ }
+
+ public void start() {
+ this.handler.start();
+ }
+
+ // Rethrows exceptions from handler thread, and throws TimeOutException in case of time-out.
+ public T join() throws Exception {
+ handler.join();
+ if (asyncException != null) {
+ throw asyncException;
+ }
+ return callResult;
+ }
+
+ /* The handler thread is responsible for timing-out the Callable thread.
+ * The resulting thread */
+ private class HandlerThread extends Thread {
+ @Override
+ public void run() {
+ Thread thread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ /* Capture result of the call */
+ callResult = callable.call();
+ } catch (Exception e) {
+ /* In case of exception, capture for re-throw */
+ asyncException = e;
+ }
+ handler.interrupt(); // Finish early
+ }
+ };
+
+ thread.start();
+
+ try {
+ Thread.sleep(timeout);
+ } catch (InterruptedException e) {
+ // Finish early
+ return;
+ }
+
+ if (thread.isAlive()) {
+ asyncException = new TimeOutException();
+ }
+
+ // Make sure the thread is finished
+ while (thread.isAlive()) {
+ thread.interrupt();
+ }
+ }
+ }
+}