From 2b97ed6d238a0db1e2cf7bdf15349e90eaaa8dfc Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 12 Sep 2015 17:29:31 +0200 Subject: Bug 1213 (related): Fix TaskBase, RunnableTask and FunctionTask implementation and semantics - TaskBase - requires 'volatile boolean isExecuted' for atomic query of same semantics - fix isInQueue(): condition was reverse in regars to 'isExecuted' - expose 'Thread getExecutionThread()' as learned within run() method. - RunnableTask - deprecate: 'static invoke(final boolean waitUntilDone, final Runnable runnable)', since it's nonsense, use runnable.run() instead. - 'static RunnableTask invokeOnNewThread(..)' - uses InterruptSource.Thread - Persistent-Wait - Cancelable using InterruptedRuntimeException - FunctionTask - deprecate 'static U invoke(final boolean waitUntilDone, final Function func, final V... args)', since it's nonsense, use func.eval(args) instead. - 'static FunctionTask invokeOnNewThread(..)' - uses InterruptSource.Thread - Persistent-Wait - Cancelable using InterruptedRuntimeException --- src/java/com/jogamp/common/util/FunctionTask.java | 68 ++++++++++++++++------- 1 file changed, 47 insertions(+), 21 deletions(-) (limited to 'src/java/com/jogamp/common/util/FunctionTask.java') diff --git a/src/java/com/jogamp/common/util/FunctionTask.java b/src/java/com/jogamp/common/util/FunctionTask.java index 4ac64d3..5a58a34 100644 --- a/src/java/com/jogamp/common/util/FunctionTask.java +++ b/src/java/com/jogamp/common/util/FunctionTask.java @@ -30,6 +30,8 @@ package com.jogamp.common.util; import java.io.PrintStream; +import com.jogamp.common.JogampRuntimeException; + /** * Helper class to provide a Runnable queue implementation with a Runnable wrapper * which notifies after execution for the invokeAndWait() semantics. @@ -40,34 +42,54 @@ public class FunctionTask extends TaskBase implements Function { protected A[] args; /** - * Invokes func. + * @deprecated Simply invoke {@link Function#eval(Object...)} + */ + public static U invoke(final boolean waitUntilDone, final Function func, final V... args) { + return func.eval(args); + } + + /** + * Invokes func on a new thread belonging to the given {@link ThreadGroup}. + *

+ * The result can be retrieved via {@link FunctionTask#getResult()}, + * using the returned instance. + *

+ * @param tg the {@link ThreadGroup} for the new thread, maybe null + * @param threadName the name for the new thread * @param waitUntilDone if true, waits until func execution is completed, otherwise returns immediately. * @param func the {@link Function} to execute. * @param args the {@link Function} arguments - * @return the {@link Function} return value + * @return the newly created and invoked {@link FunctionTask} */ - public static U invoke(final boolean waitUntilDone, final Function func, final V... args) { - Throwable throwable = null; - final Object sync = new Object(); - final FunctionTask rt = new FunctionTask( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); - final U res; - synchronized(sync) { - res = rt.eval(args); - if( waitUntilDone ) { - try { - sync.wait(); - } catch (final InterruptedException ie) { - throwable = ie; - } - if(null==throwable) { - throwable = rt.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); + public static FunctionTask invokeOnNewThread(final ThreadGroup tg, final String threadName, + final boolean waitUntilDone, final Function func, final V... args) { + final FunctionTask rt; + if( !waitUntilDone ) { + rt = new FunctionTask( func, null, true, System.err ); + final InterruptSource.Thread t = new InterruptSource.Thread(tg, rt, threadName); + rt.args = args; + t.start(); + } else { + final Object sync = new Object(); + rt = new FunctionTask( func, sync, true, null ); + final InterruptSource.Thread t = new InterruptSource.Thread(tg, rt, threadName); + synchronized(sync) { + rt.args = args; + t.start(); + while( rt.isInQueue() ) { + try { + sync.wait(); + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + final Throwable throwable = rt.getThrowable(); + if(null!=throwable) { + throw new JogampRuntimeException(throwable); + } } } } - return res; + return rt; } /** @@ -124,6 +146,8 @@ public class FunctionTask extends TaskBase implements Function { */ @Override public final void run() { + execThread = Thread.currentThread(); + final A[] args = this.args; this.args = null; this.result = null; @@ -144,6 +168,7 @@ public class FunctionTask extends TaskBase implements Function { } } finally { tExecuted = System.currentTimeMillis(); + isExecuted = true; } } else { synchronized (syncObject) { @@ -161,6 +186,7 @@ public class FunctionTask extends TaskBase implements Function { } } finally { tExecuted = System.currentTimeMillis(); + isExecuted = true; syncObject.notifyAll(); } } -- cgit v1.2.3