Re: CompletableFuture#postComplete() can be invoked concurrently?

Alex Otenko via Concurrency-interest <[email protected]> Sun, 23 Aug 2020 07:36:57 +0100
Newsgroups gmane.comp.java.jsr.166-concurrency
Message-ID <CANkgWKh5DJ7q6SHN6ke6EwcxoaMqeKutwARCD6omU8wq7f4kJA@mail.gmail.com>
Can you outline a high level outcome of the race vs expected outcome?

Alex

On Sun, 23 Aug 2020, 04:44 Liu via Concurrency-interest, <
[email protected]> wrote:

> It is kind of difficult to test it, because it all depend on
> special Thread execution order.
> I can't think of the test case temporarily.
>
> Let my opinion simpler.
>
>
> http://hg.openjdk.java.net/jdk/jdk15/file/d2c6eb3b2c8d/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java#l615
>
> In JDK15, CompletableFuture.UniApply#tryFire(), I think
> it should be like this:
>
>     @SuppressWarnings("serial")
>     static final class UniApply<T,V> extends UniCompletion<T,V> {
>         Function<? super T,? extends V> fn;
>         UniApply(Executor executor, CompletableFuture<V> dep,
>                  CompletableFuture<T> src,
>                  Function<? super T,? extends V> fn) {
>             super(executor, dep, src); this.fn = fn;
>         }
>         final CompletableFuture<V> tryFire(int mode) {
>             CompletableFuture<V> d; CompletableFuture<T> a;
>             Object r; Throwable x; Function<? super T,? extends V> f;
>             if ((a = src) == null || (r = a.result) == null
>                 || (d = dep) == null || (f = fn) == null)
>                 return null;
>             tryComplete: if (d.result == null) {
>                 if (r instanceof AltResult) {
>                     if ((x = ((AltResult)r).ex) != null) {
>                         if (!claim())         //before completeThrowable,
> it should be claimed (this two lines is added by me)
>                             return null;
>                         d.completeThrowable(x, r);
>                         break tryComplete;
>                     }
>                     r = null;
>                 }
>                 try {
>                     if (mode <= 0 && !claim())
>                         return null;
>                     else {
>                         @SuppressWarnings("unchecked") T t = (T) r;
>                         d.completeValue(f.apply(t));
>                     }
>                 } catch (Throwable ex) {
>                     d.completeThrowable(ex);
>                 }
>             }
>             src = null; dep = null; fn = null;
>             return d.postFire(a, mode);
>         }
>     }
>
> before completeThrowable, it should be claimed just like following code.
> This is mean to avoid two diffrent threads can invoke tryFire on same
> Object,
> and to avoid it will both do the d.completeThrowable(x, r) successfully
> and do
> d.postFire(a, mode) both.
>
> Or you can tell me, Why not need to claim() before d.completeThrowable(x,
> r).
> I suppose it is necessary.
>
> _______________________________________________
> Concurrency-interest mailing list
> [email protected]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

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