You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by rw...@apache.org on 2017/10/05 22:34:18 UTC

svn commit: r1811271 - in /pivot/trunk: core/src/org/apache/pivot/util/concurrent/Task.java wtk/src/org/apache/pivot/wtk/WTKTaskListener.java

Author: rwhitcomb
Date: Thu Oct  5 22:34:18 2017
New Revision: 1811271

URL: http://svn.apache.org/viewvc?rev=1811271&view=rev
Log:
PIVOT-1009: Add a field to Task to record (as a WeakReference) what the thread
was that executed the task.
Add an accessor to get the value.
Add a new class WTKTaskListener that implements a default piece of code for
the "executeFailed" callback that calls the
ApplicationContext.uncaughtExceptionHandler
with the Task fault value, along with the thread context the Task was run
under.

Added:
    pivot/trunk/wtk/src/org/apache/pivot/wtk/WTKTaskListener.java
Modified:
    pivot/trunk/core/src/org/apache/pivot/util/concurrent/Task.java

Modified: pivot/trunk/core/src/org/apache/pivot/util/concurrent/Task.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/util/concurrent/Task.java?rev=1811271&r1=1811270&r2=1811271&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/util/concurrent/Task.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/util/concurrent/Task.java Thu Oct  5 22:34:18 2017
@@ -16,10 +16,13 @@
  */
 package org.apache.pivot.util.concurrent;
 
+import java.lang.ref.WeakReference;
 import java.util.concurrent.AbstractExecutorService;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.pivot.util.Utils;
+
 /**
  * Abstract base class for "tasks". A task is an asynchronous operation that may
  * optionally return a value.
@@ -37,6 +40,10 @@ public abstract class Task<V> {
             V resultLocal = null;
             Throwable faultLocal = null;
 
+            synchronized (Task.this) {
+                Task.this.taskThread = new WeakReference<Thread>(Thread.currentThread());
+            }
+
             try {
                 resultLocal = execute();
             } catch (Throwable throwable) {
@@ -103,6 +110,7 @@ public abstract class Task<V> {
     private V result = null;
     private Throwable fault = null;
     private TaskListener<V> taskListener = null;
+    private WeakReference<Thread> taskThread = null;
 
     protected volatile long timeout = Long.MAX_VALUE;
     protected volatile boolean abort = false;
@@ -117,9 +125,7 @@ public abstract class Task<V> {
     }
 
     public Task(ExecutorService executorService) {
-        if (executorService == null) {
-            throw new IllegalArgumentException("executorService is null.");
-        }
+        Utils.checkNull(executorService, "executorService");
 
         this.executorService = executorService;
     }
@@ -159,13 +165,8 @@ public abstract class Task<V> {
      */
     public synchronized void execute(TaskListener<V> taskListenerArgument,
         ExecutorService executorServiceArgument) {
-        if (taskListenerArgument == null) {
-            throw new IllegalArgumentException("taskListener is null.");
-        }
-
-        if (executorServiceArgument == null) {
-            throw new IllegalThreadStateException("executorService is null.");
-        }
+        Utils.checkNull(taskListenerArgument, "taskListener");
+        Utils.checkNull(executorServiceArgument, "executorService");
 
         if (this.taskListener != null) {
             throw new IllegalThreadStateException("Task is already pending.");
@@ -175,6 +176,7 @@ public abstract class Task<V> {
 
         result = null;
         fault = null;
+        taskThread = null;
         abort = false;
 
         // Create a new execute callback and post it to the executor service
@@ -213,6 +215,16 @@ public abstract class Task<V> {
     }
 
     /**
+     * Returns the thread that was used to execute this task in the background.
+     *
+     * @return The background thread or <tt>null</tt> if the weak reference was
+     * already cleared or if the thread hasn't started yet.
+     */
+    public synchronized Thread getBackgroundThread() {
+        return taskThread == null ? null : taskThread.get();
+    }
+
+    /**
      * Returns the pending state of the task.
      *
      * @return <tt>true</tt> if the task is awaiting execution or currently

Added: pivot/trunk/wtk/src/org/apache/pivot/wtk/WTKTaskListener.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/WTKTaskListener.java?rev=1811271&view=auto
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/WTKTaskListener.java (added)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/WTKTaskListener.java Thu Oct  5 22:34:18 2017
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.wtk;
+
+import org.apache.pivot.util.concurrent.Task;
+import org.apache.pivot.util.concurrent.TaskListener;
+
+
+/**
+ * Default implementation of the {@link TaskListener} interface
+ * with default implementations of the methods.
+ */
+public class WTKTaskListener<V> implements TaskListener<V> {
+    @Override
+    public void taskExecuted(Task<V> task) {
+        // Empty block
+    }
+
+    /**
+     * Calls the default {@link ApplicationContext#handleUncaughtException(Thread,Throwable)}
+     * with the {@link Task#getBackgroundThread} and {@link Task#getFault}.
+     */
+    @Override
+    public void executeFailed(Task<V> task) {
+        ApplicationContext.handleUncaughtException(task.getBackgroundThread(), task.getFault());
+    }
+}