From b1eb7ca6b9d7dec7ff62c1f1e8ef0a0545724d2f Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Mon, 18 Mar 2013 03:00:45 +0100
Subject: Function- RunnableTask: Add PrintStream 'exceptionOut' argument
 allowing non blocking exceptions to be shown.

Exceptions occuring on non blocking off-thread tasks shall at least be made visible
while not allowed to crash the system.
---
 src/java/com/jogamp/common/util/FunctionTask.java | 20 ++++++++++++-----
 src/java/com/jogamp/common/util/RunnableTask.java | 26 ++++++++++++++++-------
 src/java/com/jogamp/common/util/TaskBase.java     | 10 ++++++---
 src/java/com/jogamp/common/util/locks/Lock.java   |  8 ++++---
 4 files changed, 45 insertions(+), 19 deletions(-)

(limited to 'src/java')

diff --git a/src/java/com/jogamp/common/util/FunctionTask.java b/src/java/com/jogamp/common/util/FunctionTask.java
index 35720a0..8238aff 100644
--- a/src/java/com/jogamp/common/util/FunctionTask.java
+++ b/src/java/com/jogamp/common/util/FunctionTask.java
@@ -28,6 +28,8 @@
  
 package com.jogamp.common.util;
 
+import java.io.PrintStream;
+
 /**
  * Helper class to provide a Runnable queue implementation with a Runnable wrapper
  * which notifies after execution for the <code>invokeAndWait()</code> semantics.
@@ -47,7 +49,7 @@ public class FunctionTask<R,A> extends TaskBase implements Function<R,A> {
     public static <U,V> U invoke(boolean waitUntilDone, Function<U,V> func, V... args) {
         Throwable throwable = null;
         final Object sync = new Object();
-        final FunctionTask<U,V> rt = new FunctionTask<U,V>( func, waitUntilDone ? sync : null, true );
+        final FunctionTask<U,V> rt = new FunctionTask<U,V>( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err );
         final U res;
         synchronized(sync) {
             res = rt.eval(args);
@@ -75,11 +77,13 @@ public class FunctionTask<R,A> extends TaskBase implements Function<R,A> {
      * @param runnable the user action
      * @param syncObject the synchronization object the caller shall wait until <code>runnable</code> execution is completed,
      *                   or <code>null</code> if waiting is not desired. 
-     * @param catchExceptions if true, exception during <code>runnable</code> execution are catched, otherwise not.
-     *                        Use {@link #getThrowable()} to determine whether an exception has been catched. 
+     * @param catchExceptions Influence an occurring exception during <code>runnable</code> execution.
+     *                        If <code>true</code>, the exception is silenced and can be retrieved via {@link #getThrowable()},
+     *                        otherwise the exception is thrown.
+     * @param exceptionOut If not <code>null</code>, exceptions are written to this {@link PrintStream}.
      */
-    public FunctionTask(Function<R,A> runnable, Object syncObject, boolean catchExceptions) {
-        super(syncObject, catchExceptions);
+    public FunctionTask(Function<R,A> runnable, Object syncObject, boolean catchExceptions, PrintStream exceptionOut) {
+        super(syncObject, catchExceptions, exceptionOut);
         this.runnable = runnable ;
         result = null;
         args = null;
@@ -129,6 +133,9 @@ public class FunctionTask<R,A> extends TaskBase implements Function<R,A> {
                 this.result = runnable.eval(args);
             } catch (Throwable t) {
                 runnableException = t;
+                if(null != exceptionOut) {
+                    t.printStackTrace(exceptionOut);
+                }
                 if(!catchExceptions) {
                     throw new RuntimeException(runnableException);
                 }
@@ -141,6 +148,9 @@ public class FunctionTask<R,A> extends TaskBase implements Function<R,A> {
                     this.result = runnable.eval(args);
                 } catch (Throwable t) {
                     runnableException = t;
+                    if(null != exceptionOut) {
+                        t.printStackTrace(exceptionOut);
+                    }
                     if(!catchExceptions) {
                         throw new RuntimeException(runnableException);
                     }
diff --git a/src/java/com/jogamp/common/util/RunnableTask.java b/src/java/com/jogamp/common/util/RunnableTask.java
index 5d9441a..ee484e1 100644
--- a/src/java/com/jogamp/common/util/RunnableTask.java
+++ b/src/java/com/jogamp/common/util/RunnableTask.java
@@ -28,6 +28,8 @@
  
 package com.jogamp.common.util;
 
+import java.io.PrintStream;
+
 /**
  * Helper class to provide a Runnable queue implementation with a Runnable wrapper
  * which notifies after execution for the <code>invokeAndWait()</code> semantics.
@@ -43,7 +45,7 @@ public class RunnableTask extends TaskBase {
     public static void invoke(boolean waitUntilDone, Runnable runnable) {
         Throwable throwable = null;
         final Object sync = new Object();
-        final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true ); 
+        final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); 
         synchronized(sync) {
             rt.run();
             if( waitUntilDone ) {
@@ -66,16 +68,18 @@ public class RunnableTask extends TaskBase {
      * Create a RunnableTask object w/ synchronization,
      * ie. suitable for <code>invokeAndWait()</code>, i.e. {@link #invoke(boolean, Runnable) invoke(true, runnable)}. 
      * 
-     * @param runnable the user action
-     * @param syncObject the synchronization object if caller wait until <code>runnable</code> execution is completed,
+     * @param runnable The user action
+     * @param syncObject The synchronization object if caller wait until <code>runnable</code> execution is completed,
      *                   or <code>null</code> if waiting is not desired. 
-     * @param catchExceptions if true, exception during <code>runnable</code> execution are catched, otherwise not.
-     *                        Use {@link #getThrowable()} to determine whether an exception has been catched. 
+     * @param catchExceptions Influence an occurring exception during <code>runnable</code> execution.
+     *                        If <code>true</code>, the exception is silenced and can be retrieved via {@link #getThrowable()},
+     *                        otherwise the exception is thrown.
+     * @param exceptionOut If not <code>null</code>, exceptions are written to this {@link PrintStream}.
      */
-    public RunnableTask(Runnable runnable, Object syncObject, boolean catchExceptions) {
-        super(syncObject, catchExceptions);
+    public RunnableTask(Runnable runnable, Object syncObject, boolean catchExceptions, PrintStream exceptionOut) {
+        super(syncObject, catchExceptions, exceptionOut);
         this.runnable = runnable ;
-    }
+    } 
 
     /** Return the user action */
     public final Runnable getRunnable() {
@@ -90,6 +94,9 @@ public class RunnableTask extends TaskBase {
                 runnable.run();
             } catch (Throwable t) {
                 runnableException = t;
+                if(null != exceptionOut) {
+                    t.printStackTrace(exceptionOut);
+                }
                 if(!catchExceptions) {
                     throw new RuntimeException(runnableException);
                 }
@@ -102,6 +109,9 @@ public class RunnableTask extends TaskBase {
                     runnable.run();
                 } catch (Throwable t) {
                     runnableException = t;
+                    if(null != exceptionOut) {
+                        t.printStackTrace(exceptionOut);
+                    }
                     if(!catchExceptions) {
                         throw new RuntimeException(runnableException);
                     }
diff --git a/src/java/com/jogamp/common/util/TaskBase.java b/src/java/com/jogamp/common/util/TaskBase.java
index d2a924f..266a5b7 100644
--- a/src/java/com/jogamp/common/util/TaskBase.java
+++ b/src/java/com/jogamp/common/util/TaskBase.java
@@ -28,6 +28,8 @@
  
 package com.jogamp.common.util;
 
+import java.io.PrintStream;
+
 /**
  * Helper class to provide a Runnable queue implementation with a Runnable wrapper
  * which notifies after execution for the <code>invokeAndWait()</code> semantics.
@@ -35,6 +37,7 @@ package com.jogamp.common.util;
 public abstract class TaskBase implements Runnable {
     protected final Object syncObject;
     protected final boolean catchExceptions;
+    protected final PrintStream exceptionOut;
     
     protected Object attachment;
     protected Throwable runnableException;
@@ -42,9 +45,10 @@ public abstract class TaskBase implements Runnable {
     protected volatile long tExecuted;
     protected volatile boolean isFlushed;
 
-    protected TaskBase(Object syncObject, boolean catchExceptions) {
-        this.syncObject = syncObject ;
-        this.catchExceptions = catchExceptions ;
+    protected TaskBase(Object syncObject, boolean catchExceptions, PrintStream exceptionOut) {
+        this.syncObject = syncObject;
+        this.catchExceptions = catchExceptions;
+        this.exceptionOut = exceptionOut;
         tCreated = System.currentTimeMillis();
         tStarted = 0;
         tExecuted = 0;
diff --git a/src/java/com/jogamp/common/util/locks/Lock.java b/src/java/com/jogamp/common/util/locks/Lock.java
index 33a093b..ea29763 100644
--- a/src/java/com/jogamp/common/util/locks/Lock.java
+++ b/src/java/com/jogamp/common/util/locks/Lock.java
@@ -41,13 +41,15 @@ public interface Lock {
     /** Enable via the property <code>jogamp.debug.Lock</code> */
     public static final boolean DEBUG = Debug.debug("Lock");
 
-    /** Defines the default {@link #TIMEOUT} value */
+    /** The default {@link #TIMEOUT} value, of {@value} ms */
     public static final long DEFAULT_TIMEOUT = 5000; // 5s default timeout
     
     /** 
-     * Defines the <code>TIMEOUT</code> for {@link #lock()} in ms,
-     * and defaults to {@link #DEFAULT_TIMEOUT}.<br>
+     * The <code>TIMEOUT</code> for {@link #lock()} in ms,
+     * defaults to {@link #DEFAULT_TIMEOUT}.
+     * <p>
      * It can be overridden via the system property <code>jogamp.common.utils.locks.Lock.timeout</code>.
+     * </p>
      */
     public static final long TIMEOUT = Debug.getLongProperty("jogamp.common.utils.locks.Lock.timeout", true, DEFAULT_TIMEOUT);
 
-- 
cgit v1.2.3