GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
FunctionTask.java
Go to the documentation of this file.
1/**
2 * Copyright 2013 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.common.util;
30
31import java.io.PrintStream;
32
33import com.jogamp.common.JogampRuntimeException;
34
35/**
36 * Helper class to provide a Runnable queue implementation with a Runnable wrapper
37 * which notifies after execution for the <code>invokeAndWait()</code> semantics.
38 */
39public class FunctionTask<R,A> extends TaskBase implements Function<R,A> {
41 protected R result;
42 protected A[] args;
43
44 /**
45 * Invokes <code>func</code> on the current {@link Thread}.
46 * <p>
47 * The result can be retrieved via {@link FunctionTask#getResult()},
48 * using the returned instance.
49 * </p>
50 * @param func the {@link Function} to execute.
51 * @param args the {@link Function} arguments
52 * @return the newly created and invoked {@link FunctionTask}
53 * @since 2.4.0
54 */
55 public static <U,V> FunctionTask<U,V> invokeOnCurrentThread(final Function<U,V> func, final V... args) {
56 final FunctionTask<U,V> rt = new FunctionTask<U,V>( func, null, false, null);
57 rt.args = args;
58 rt.run();
59 return rt;
60 }
61
62 /**
63 * Invokes <code>func</code> on a new {@link InterruptSource.Thread},
64 * see {@link InterruptSource.Thread#Thread(ThreadGroup, Runnable, String)} for details.
65 * <p>
66 * The result can be retrieved via {@link FunctionTask#getResult()},
67 * using the returned instance.
68 * </p>
69 * @param tg the {@link ThreadGroup} for the new thread, maybe <code>null</code>
70 * @param threadName the name for the new thread, maybe <code>null</code>
71 * @param waitUntilDone if <code>true</code>, waits until <code>func</code> execution is completed, otherwise returns immediately.
72 * @param func the {@link Function} to execute.
73 * @param args the {@link Function} arguments
74 * @return the newly created and invoked {@link FunctionTask}
75 * @since 2.3.2
76 */
77 public static <U,V> FunctionTask<U,V> invokeOnNewThread(final ThreadGroup tg, final String threadName,
78 final boolean waitUntilDone, final Function<U,V> func, final V... args) {
79 final FunctionTask<U,V> rt;
80 if( !waitUntilDone ) {
81 rt = new FunctionTask<U,V>( func, null, true, System.err );
82 final InterruptSource.Thread t = InterruptSource.Thread.create(tg, rt, threadName);
83 rt.args = args;
84 t.start();
85 } else {
86 final Object sync = new Object();
87 rt = new FunctionTask<U,V>( func, sync, true, null );
88 final InterruptSource.Thread t = InterruptSource.Thread.create(tg, rt, threadName);
89 synchronized(sync) {
90 rt.args = args;
91 t.start();
92 while( rt.isInQueue() ) {
93 try {
94 sync.wait();
95 } catch (final InterruptedException ie) {
96 throw new InterruptedRuntimeException(ie);
97 }
98 final Throwable throwable = rt.getThrowable();
99 if(null!=throwable) {
100 throw new JogampRuntimeException(throwable);
101 }
102 }
103 }
104 }
105 return rt;
106 }
107
108 /**
109 * Create a RunnableTask object w/ synchronization,
110 * ie. suitable for <code>invokeAndWait()</code>.
111 *
112 * @param runnable the user action
113 * @param syncObject the synchronization object the caller shall wait until <code>runnable</code> execution is completed,
114 * or <code>null</code> if waiting is not desired.
115 * @param catchExceptions Influence an occurring exception during <code>runnable</code> execution.
116 * If <code>true</code>, the exception is silenced and can be retrieved via {@link #getThrowable()},
117 * otherwise the exception is thrown.
118 * @param exceptionOut If not <code>null</code>, exceptions are written to this {@link PrintStream}.
119 */
120 public FunctionTask(final Function<R,A> runnable, final Object syncObject, final boolean catchExceptions, final PrintStream exceptionOut) {
122 this.runnable = runnable ;
123 result = null;
124 args = null;
125 }
126
127 /** Return the user action */
128 public final Function<R,A> getRunnable() {
129 return runnable;
130 }
131
132 /**
133 * Sets the arguments for {@link #run()}.
134 * They will be cleared after calling {@link #run()} or {@link #eval(Object...)}.
135 */
136 public final void setArgs(final A... args) {
137 this.args = args;
138 }
139
140 /**
141 * Retrieves the cached result of {@link #run()}
142 * and is cleared within this method.
143 */
144 public final R getResult() {
145 final R res = result;
146 result = null;
147 return res;
148 }
149
150 /**
151 * {@inheritDoc}
152 * <p>
153 * Calls {@link #eval(Object...)}.
154 * </p>
155 * <p>
156 * You may set the {@link #eval(Object...)} arguments via {@link #setArgs(Object...)}
157 * and retrieve the result via {@link #getResult()}.
158 * </p>
159 */
160 @Override
161 public final void run() {
162 execThread = Thread.currentThread();
163
164 final A[] args = this.args;
165 this.args = null;
166 this.result = null;
167 runnableException = null;
168 tStarted = System.currentTimeMillis();
169 if(null == syncObject) {
170 try {
171 this.result = runnable.eval(args);
172 } catch (final Throwable t) {
174 if(null != exceptionOut) {
175 exceptionOut.println("FunctionTask.run(): "+getExceptionOutIntro()+" exception occured on thread "+Thread.currentThread().getName()+": "+toString());
177 t.printStackTrace(exceptionOut);
178 }
179 if(!catchExceptions) {
180 throw new RuntimeException(runnableException);
181 }
182 } finally {
183 tExecuted = System.currentTimeMillis();
184 isExecuted = true;
185 }
186 } else {
187 synchronized (syncObject) {
188 try {
189 this.result = runnable.eval(args);
190 } catch (final Throwable t) {
192 if(null != exceptionOut) {
193 exceptionOut.println("FunctionTask.run(): "+getExceptionOutIntro()+" exception occured on thread "+Thread.currentThread().getName()+": "+toString());
195 t.printStackTrace(exceptionOut);
196 }
197 if(!catchExceptions) {
198 throw new RuntimeException(runnableException);
199 }
200 } finally {
201 tExecuted = System.currentTimeMillis();
202 isExecuted = true;
203 syncObject.notifyAll();
204 }
205 }
206 }
207 }
208
209 @Override
210 public final R eval(final A... args) {
211 this.args = args;
212 run();
213 final R res = result;
214 result = null;
215 return res;
216 }
217}
218
A generic unchecked exception for Jogamp errors used throughout the binding as a substitute for Runti...
Helper class to provide a Runnable queue implementation with a Runnable wrapper which notifies after ...
static< U, V > FunctionTask< U, V > invokeOnNewThread(final ThreadGroup tg, final String threadName, final boolean waitUntilDone, final Function< U, V > func, final V... args)
Invokes func on a new InterruptSource.Thread, see InterruptSource.Thread#Thread(ThreadGroup,...
final R eval(final A... args)
Implementation may compute variable args list and returns a result.
FunctionTask(final Function< R, A > runnable, final Object syncObject, final boolean catchExceptions, final PrintStream exceptionOut)
Create a RunnableTask object w/ synchronization, ie.
final void setArgs(final A... args)
Sets the arguments for run().
final R getResult()
Retrieves the cached result of run() and is cleared within this method.
static< U, V > FunctionTask< U, V > invokeOnCurrentThread(final Function< U, V > func, final V... args)
Invokes func on the current Thread.
final Function< R, A > getRunnable()
Return the user action.
java.lang.Thread specialization implementing InterruptSource to track java.lang.Thread#interrupt() ca...
static Thread create(final ThreadGroup tg, final Runnable target, final String name)
Depending on whether name is null, either Thread(ThreadGroup, Runnable, String) or Thread(ThreadGroup...
Unchecked exception propagating an InterruptedException where handling of the latter is not desired.
Helper class to provide a Runnable queue implementation with a Runnable wrapper which notifies after ...
Definition: TaskBase.java:39
final String getExceptionOutIntro()
Definition: TaskBase.java:82
final Throwable getThrowable()
Definition: TaskBase.java:171
volatile boolean isExecuted
Definition: TaskBase.java:57
final PrintStream exceptionOut
Definition: TaskBase.java:50
Generic function interface to perform an action w/ given optional arguments producing an optional res...
Definition: Function.java:40
Interface exposing java.lang.Thread#interrupt() source, intended for java.lang.Thread specializations...