Future.isCompletedNormally Future.isCompletedAbnormally

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Viktor Klang

Making the default methods blocking would be horrible IMO.

--
Cheers,

On 5 Mar 2015 10:48, "Martin Buchholz" <[hidden email]> wrote:
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Viktor Klang

Never mind, saw the !IsDone()

--
Cheers,

On 5 Mar 2015 11:40, "Viktor Klang" <[hidden email]> wrote:

Making the default methods blocking would be horrible IMO.

--
Cheers,

On 5 Mar 2015 10:48, "Martin Buchholz" <[hidden email]> wrote:
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Joe Bowbeer
In reply to this post by Viktor Klang
I have a similar complaint as Viktor. These default implementations seem too heavyweight.


Sent from Mailbox


On Wed, Mar 4, 2015 at 8:49 PM, Viktor Klang <[hidden email]> wrote:

Making the default methods blocking would be horrible IMO.

--
Cheers,

On 5 Mar 2015 10:48, "Martin Buchholz" <[hidden email]> wrote:
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormallyFuture.isCompletedAbnormally

David Holmes-6
In reply to this post by Viktor Klang

Victor,
 
They aren't blocking - you will only get to the get() if isDone() is true, so all you are accessing is the result to see if it is a real result or an exception occurred.
 
David
-----Original Message-----
From: [hidden email] [mailto:[hidden email]]On Behalf Of Viktor Klang
Sent: Thursday, 5 March 2015 2:40 PM
To: Martin Buchholz
Cc: concurrency-interest
Subject: Re: [concurrency-interest] Future.isCompletedNormallyFuture.isCompletedAbnormally

Making the default methods blocking would be horrible IMO.

--
Cheers,

On 5 Mar 2015 10:48, "Martin Buchholz" <[hidden email]> wrote:
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormallyFuture.isCompletedAbnormally

David Holmes-6
In reply to this post by Viktor Klang

Never mind, just saw your follow up :(
 
David
-----Original Message-----
From: [hidden email] [mailto:[hidden email]]On Behalf Of Viktor Klang
Sent: Thursday, 5 March 2015 2:44 PM
To: Martin Buchholz
Cc: concurrency-interest
Subject: Re: [concurrency-interest] Future.isCompletedNormallyFuture.isCompletedAbnormally

Never mind, saw the !IsDone()

--
Cheers,

On 5 Mar 2015 11:40, "Viktor Klang" <[hidden email]> wrote:

Making the default methods blocking would be horrible IMO.

--
Cheers,

On 5 Mar 2015 10:48, "Martin Buchholz" <[hidden email]> wrote:
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Vitaly Davidovich
In reply to this post by Martin Buchholz-3

What's the motivation for doing that? Why moving this up in the hierarchy is desired? These methods seem like utilities one would write on top of their own concrete implementations.

Also, what's the purpose of the labeled loop? Moreover, what if get () on that impl always throws interrupted exception - this loops forever? I guess I don't like this because it makes assumptions about how the implementation behaves in get ().

sent from my phone

On Mar 4, 2015 10:48 PM, "Martin Buchholz" <[hidden email]> wrote:
ForkJoinTask is a Future implementation with existing methods isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default implementations and efficient implementations on FutureTask and CompletableFuture. 

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
In reply to this post by Joe Bowbeer


On Wed, Mar 4, 2015 at 8:56 PM, <[hidden email]> wrote:
I have a similar complaint as Viktor. These default implementations seem too heavyweight.

Most concrete implementations will sprout efficient implementations. And the cost of the default implementations is "only" an exception throw/catch, and that only when the future failed, which is supposed to be rare.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
In reply to this post by Vitaly Davidovich


On Wed, Mar 4, 2015 at 9:23 PM, Vitaly Davidovich <[hidden email]> wrote:

What's the motivation for doing that? Why moving this up in the hierarchy is desired? These methods seem like utilities one would write on top of their own concrete implementations.


The motivation is "if these methods make sense for ForkJoinTask, then they make sense for all Futures". 

Also, what's the purpose of the labeled loop? Moreover, what if get () on that impl always throws interrupted exception - this loops forever? I guess I don't like this because it makes assumptions about how the implementation behaves in get ().


Let's first decide whether we want these methods before fixing esoteric bugs (throwing InterruptedException without clearing the interrupt status, really?)
 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Vitaly Davidovich

Personally,  I'm not seeing the "makes sense for FJT thus also for higher level Future" reasoning, but maybe that's just me.

It's not about resetting the interrupt status (which happens as well), but even simpler case where someone decided to throw interrupted exception on each get ().  I guess what I don't like about this is control flow (with possible infinite looping) based on calling into the abyss (i.e. some random Future impl).

Moreover, as mentioned, these seem like util/helper methods and not a core concept to the interface - I'm not sure slapping them on via default methods is worth the clutter.

sent from my phone

On Mar 5, 2015 12:33 AM, "Martin Buchholz" <[hidden email]> wrote:


On Wed, Mar 4, 2015 at 9:23 PM, Vitaly Davidovich <[hidden email]> wrote:

What's the motivation for doing that? Why moving this up in the hierarchy is desired? These methods seem like utilities one would write on top of their own concrete implementations.


The motivation is "if these methods make sense for ForkJoinTask, then they make sense for all Futures". 

Also, what's the purpose of the labeled loop? Moreover, what if get () on that impl always throws interrupted exception - this loops forever? I guess I don't like this because it makes assumptions about how the implementation behaves in get ().


Let's first decide whether we want these methods before fixing esoteric bugs (throwing InterruptedException without clearing the interrupt status, really?)
 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Joe Bowbeer
In reply to this post by Martin Buchholz-3
To clarify my position: These methods would be fine if the default implementations were not so complicated (aka heavyweight, and prone to failure when applied to custom Future implementations).

However, I doubt that a better implementation is possible without introducing a sibling of get() to support this kind of use.



Sent from Mailbox


On Wed, Mar 4, 2015 at 9:50 PM, Martin Buchholz <[hidden email]> wrote:



On Wed, Mar 4, 2015 at 9:23 PM, Vitaly Davidovich <[hidden email]> wrote:

What's the motivation for doing that? Why moving this up in the hierarchy is desired? These methods seem like utilities one would write on top of their own concrete implementations.


The motivation is "if these methods make sense for ForkJoinTask, then they make sense for all Futures". 

Also, what's the purpose of the labeled loop? Moreover, what if get () on that impl always throws interrupted exception - this loops forever? I guess I don't like this because it makes assumptions about how the implementation behaves in get ().


Let's first decide whether we want these methods before fixing esoteric bugs (throwing InterruptedException without clearing the interrupt status, really?)
 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

thurstonn
In reply to this post by Martin Buchholz-3
What would be the memory consistency effects of

isCompletedNormally() ==> true      be?


I assume the "asynchronous computation" would happen-before in that case.


Also, just for discussion, what if you have some :

DefaultFuture<T>(default:T, () -> T) implements Future<T>

what would the semantics of isCompletedAbnormally() be in such a case?  Might burden the implementation unnecessarily in such a case to strictly implement it.

I'm not sure how FJP uses FJT's methods, but it doesn't necessarily follow that those methods should be promoted to the base interface.
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
Even isDone is not (yet) mentioned in

Memory Consistency Properties

in http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html

All of the is* methods would (obviously) have the same happens-before semantics.


On Wed, Mar 4, 2015 at 10:58 PM, thurstonn <[hidden email]> wrote:
What would be the memory consistency effects of

isCompletedNormally() ==> true      be?


I assume the "asynchronous computation" would happen-before in that case.


Also, just for discussion, what if you have some :

DefaultFuture<T>(default:T, () -> T) implements Future<T>

what would the semantics of isCompletedAbnormally() be in such a case?
Might burden the implementation unnecessarily in such a case to strictly
implement it.

I'm not sure how FJP uses FJT's methods, but it doesn't necessarily follow
that those methods should be promoted to the base interface.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Future-isCompletedNormally-Future-isCompletedAbnormally-tp12386p12397.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

thurstonn
Martin Buchholz-3 wrote
Even isDone is not (yet) mentioned in
Memory Consistency Properties

in
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html

All of the is* methods would (obviously) have the same happens-before
semantics.
But that's deliberate - isDone() can't have any specified memory consistency rules, since
the following **doesn't** hold:
 isDone == true iff isCompletedNormally() == true

The usefulness of isCompletedNormally() would lie exactly in this, e,g,

if (f.isCompletedNormally())
   do something  //all done
else if (waitedlongenough())
   f.cancel()
   schedule a backup/replacement execution

That would be useful, especially given that get() throws checked exceptions, which makes the above presently very unwieldy.
isCompletedNormally should have the same memory consistency effects as a "successful" return from f.get().  In fact, I'd prefer it be renamed to wasSuccessful() (but what's in a name?)




Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
Perhaps Doug can explain why isCompletedNormally and isCompletedAbnormally landed in ForkJoinTask but no other Future implementation.

On Thu, Mar 5, 2015 at 11:07 AM, thurstonn <[hidden email]> wrote:

> All of the is* methods would (obviously) have the same happens-before
> semantics.

But that's deliberate - isDone() can't have any specified memory consistency
rules, since
the following **doesn't** hold:
 isDone == true iff isCompletedNormally() == true


I don't see why that's true.  I expect the action in the thread that makes the future done (setting result or exceptional value) happens-before actions isDone returning true
 
The usefulness of isCompletedNormally() would lie exactly in this, e,g,

if (f.isCompletedNormally())
   do something  //all done
else if (waitedlongenough())
   f.cancel()
   schedule a backup/replacement execution


I don't think eliding the try/catch block is good motivation.


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Luke Sandberg
I think these would be pretty useful (isCancelled() is pretty useful), I would also be interested in efficient methods to get the failure cause of a future (without paying the cost of an ExecutionException).  A lot of time the executionexception contains no useful information (if a library is dereferencing a users future), and so i end up discarding the EE or replacing it with something more useful. 

On Thu, Mar 5, 2015 at 11:58 AM, Martin Buchholz <[hidden email]> wrote:
Perhaps Doug can explain why isCompletedNormally and isCompletedAbnormally landed in ForkJoinTask but no other Future implementation.

On Thu, Mar 5, 2015 at 11:07 AM, thurstonn <[hidden email]> wrote:

> All of the is* methods would (obviously) have the same happens-before
> semantics.

But that's deliberate - isDone() can't have any specified memory consistency
rules, since
the following **doesn't** hold:
 isDone == true iff isCompletedNormally() == true


I don't see why that's true.  I expect the action in the thread that makes the future done (setting result or exceptional value) happens-before actions isDone returning true
 
The usefulness of isCompletedNormally() would lie exactly in this, e,g,

if (f.isCompletedNormally())
   do something  //all done
else if (waitedlongenough())
   f.cancel()
   schedule a backup/replacement execution


I don't think eliding the try/catch block is good motivation.


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Joe Bowbeer
More comments and suggestions

1. I think "isCompletedAbnormally" is confusing in relation to the existing method isCancelled.  Is cancellation an abnormal completion?  I think this is debatable and therefore a point of confusion.  I think these names are clearer:

hasFailed()
hasCompletedWithException()

2. hasCompletedNormally instead of isCompletedNormally?

3. Would a non-blocking sibling of get() be a more basic building block for these methods? For example:

getOptional() returns an Optional that is present if f.isDone, empty if !f.isDone, and otherwise throws the usual exceptions?  (Except it does *not* throw InterruptedException?)

--Joe

On Sat, Mar 7, 2015 at 2:27 PM, Luke Sandberg <[hidden email]> wrote:
I think these would be pretty useful (isCancelled() is pretty useful), I would also be interested in efficient methods to get the failure cause of a future (without paying the cost of an ExecutionException).  A lot of time the executionexception contains no useful information (if a library is dereferencing a users future), and so i end up discarding the EE or replacing it with something more useful. 

On Thu, Mar 5, 2015 at 11:58 AM, Martin Buchholz <[hidden email]> wrote:
Perhaps Doug can explain why isCompletedNormally and isCompletedAbnormally landed in ForkJoinTask but no other Future implementation.

On Thu, Mar 5, 2015 at 11:07 AM, thurstonn <[hidden email]> wrote:

> All of the is* methods would (obviously) have the same happens-before
> semantics.

But that's deliberate - isDone() can't have any specified memory consistency
rules, since
the following **doesn't** hold:
 isDone == true iff isCompletedNormally() == true


I don't see why that's true.  I expect the action in the thread that makes the future done (setting result or exceptional value) happens-before actions isDone returning true
 
The usefulness of isCompletedNormally() would lie exactly in this, e,g,

if (f.isCompletedNormally())
   do something  //all done
else if (waitedlongenough())
   f.cancel()
   schedule a backup/replacement execution


I don't think eliding the try/catch block is good motivation.


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Chris Purcell
In reply to this post by Martin Buchholz-3

Possible alternative implementation:

default boolean isDoneSuccessfully() {
  try {
    get(this, 0, SECONDS);
    return true;
  } catch (CancellationException
      | ExecutionException
      | TimeoutException e) {
    return false;
  } catch (InterruptedException e) {
    currentThread().interrupt();
    return false;
  }
}

My understanding of hotspot optimisation (limited) suggests (a) the InterruptedExceptions, CancellationExceptions and TimeoutExceptions will be interned, (b) the optimiser is more likely to trigger (and hopefully kill the exceptions entirely?) if we keep this small.

The benefit of a default implementation over doing this by hand, apart from discoverability and overrideability, is that this is more likely to be optimised, being a common method.

(I'm assuming interruptions only occur for incomplete futures. I think that's a valid assumption, otherwise there's no non-blocking way to get a future's result.)

Chris


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
In reply to this post by Joe Bowbeer
I don't think the names of the existing methods is great, but it's not terrible, and the time for bike shedding the names is past.
(We should have objected when Doug introduced these methods)
I just noticed this method that Luke wants:



On Sat, Mar 7, 2015 at 3:32 PM, Joe Bowbeer <[hidden email]> wrote:
More comments and suggestions

1. I think "isCompletedAbnormally" is confusing in relation to the existing method isCancelled.  Is cancellation an abnormal completion?  I think this is debatable and therefore a point of confusion.  I think these names are clearer:

hasFailed()
hasCompletedWithException()

2. hasCompletedNormally instead of isCompletedNormally?

3. Would a non-blocking sibling of get() be a more basic building block for these methods? For example:

getOptional() returns an Optional that is present if f.isDone, empty if !f.isDone, and otherwise throws the usual exceptions?  (Except it does *not* throw InterruptedException?)

--Joe

On Sat, Mar 7, 2015 at 2:27 PM, Luke Sandberg <[hidden email]> wrote:
I think these would be pretty useful (isCancelled() is pretty useful), I would also be interested in efficient methods to get the failure cause of a future (without paying the cost of an ExecutionException).  A lot of time the executionexception contains no useful information (if a library is dereferencing a users future), and so i end up discarding the EE or replacing it with something more useful. 

On Thu, Mar 5, 2015 at 11:58 AM, Martin Buchholz <[hidden email]> wrote:
Perhaps Doug can explain why isCompletedNormally and isCompletedAbnormally landed in ForkJoinTask but no other Future implementation.

On Thu, Mar 5, 2015 at 11:07 AM, thurstonn <[hidden email]> wrote:

> All of the is* methods would (obviously) have the same happens-before
> semantics.

But that's deliberate - isDone() can't have any specified memory consistency
rules, since
the following **doesn't** hold:
 isDone == true iff isCompletedNormally() == true


I don't see why that's true.  I expect the action in the thread that makes the future done (setting result or exceptional value) happens-before actions isDone returning true
 
The usefulness of isCompletedNormally() would lie exactly in this, e,g,

if (f.isCompletedNormally())
   do something  //all done
else if (waitedlongenough())
   f.cancel()
   schedule a backup/replacement execution


I don't think eliding the try/catch block is good motivation.


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz-3
I just realized to my horror that existing CompletableFuture.isCompletedExceptionally and ForkJoinTask.isCompletedAbnormally have (more or less) the same semantics, and return true on cancellation.
There's no existing method that returns true on abnormal completion but not on cancellation.

Existing spec for ForkJoinTask states:

The execution status of tasks may be queried at several levels of detail: isDone() is true if a task completed in any way (including the case where a task was cancelled without executing); isCompletedNormally() is true if a task completed without cancellation or encountering an exception; isCancelled() is true if the task was cancelled (in which case getException() returns a CancellationException); and isCompletedAbnormally() is true if a task was either cancelled or encountered an exception, in which case getException() will return either the encountered exception or CancellationException.

Can we achieve general consensus that propagating some of these small convenience methods to more Future implementations is useful?

v 0.2

Index: java/util/concurrent/CompletableFuture.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- java/util/concurrent/CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ java/util/concurrent/CompletableFuture.java    9 Mar 2015 18:12:39 -0000
@@ -2314,6 +2314,29 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture completed exceptionally or was cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed exceptionally or was cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        return isCompletedExceptionally();
+    }
+
+    /**
+     * Returns {@code true} if this CompletableFuture completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: java/util/concurrent/Future.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- java/util/concurrent/Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ java/util/concurrent/Future.java    9 Mar 2015 18:12:39 -0000
@@ -110,6 +110,74 @@
     boolean isDone();
 
     /**
+     * Returns {@code true} if this task completed by throwing an exception or was cancelled.
+     *
+     * @return {@code true} if this task completed by throwing an exception or was cancelled
+     */
+    default boolean isCompletedAbnormally() {
+        if (isDone()) {
+            if (isCancelled())
+                return true;
+            // Support Future implementations that throw
+            // InterruptedException even when result is available.
+            boolean interrupted = false;
+            try {
+                retry: for (;;) {
+                    try {
+                        get();
+                    } catch (ExecutionException e) {
+                        return true;
+                    } catch (InterruptedException e) {
+                        interrupted = true;
+                        continue retry;
+                    } catch (CancellationException hmmm) {
+                        // Unexpected, given that isCancelled() returned false
+                    }
+                    break;
+                }
+            } finally {
+                if (interrupted)
+                    Thread.currentThread().interrupt();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (isDone() && !isCancelled()) {
+            // Support Future implementations that throw
+            // InterruptedException even when result is available.
+            boolean interrupted = false;
+            try {
+                retry: for (;;) {
+                    try {
+                        get();
+                        return true;
+                    } catch (ExecutionException e) {
+                    } catch (InterruptedException e) {
+                        interrupted = true;
+                        continue retry;
+                    } catch (CancellationException hmmm) {
+                        // Unexpected, given that isCancelled() returned false
+                    }
+                    break;
+                }
+            } finally {
+                if (interrupted)
+                    Thread.currentThread().interrupt();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: java/util/concurrent/FutureTask.java
===================================================================
RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- java/util/concurrent/FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ java/util/concurrent/FutureTask.java    9 Mar 2015 18:12:39 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }
 
+    /**
+     * Returns {@code true} if this task completed by throwing an exception or was cancelled.
+     *
+     * @return {@code true} if this task completed by throwing an exception or was cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL || s >= CANCELLED;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest