Calling StructuredTaskScope.join() several times inside the same scope

Alan Bateman Alan.Bateman at oracle.com
Mon Sep 4 07:07:50 UTC 2023


On 04/09/2023 07:38, Remi Forax wrote:
> Resent because it seems that the mailing list has some issue.
I'm not aware of any issues with the mailing list. Ron has the mailman 
admin access for this list and might be able to see if there your mails 
are locked for some reason.

> ---
>
> Hi all,
> I've a problem with the actual semantics of StructuredTaskScope.shutdown()/join().
>
> Let say, i want to get the result of the first two tasks and then the result of the next two.
> I can us the fact that I call call join() several times and write
>
>          try(var sts = new StructuredTaskScope<>()) {
>              var task1 = sts.fork(() -> 1);
>              var task2 = sts.fork(() -> 2);
>              sts.join();
>              System.out.println(task1.get() + " " + task2.get());  // 1 2
>
>              var task3 = sts.fork(() -> 3);
>              var task4 = sts.fork(() -> 4);
>              sts.join();
>              System.out.println(task3.get() + " " + task4.get());  // 3 4
>          }
The reason it allows multiple rounds of forking+join by a subclass that 
exposes some API to consume the outcome of a round of forking. It's a 
topic that needs more feedback and real-world usage before we can decide 
anything. In your examples here, then I assume it's just for 
illustration purposes as there is no need to re-use the scope.

>
> But let say I want to the same with a ShutdownOnSucess()
>
>          try(var sts = new StructuredTaskScope.ShutdownOnSuccess<>()) {
>              var task1 = sts.fork(() -> 1);
>              var task2 = sts.fork(() -> 2);
>              sts.join();
>              System.out.println(sts.result());  // 1
>
>              var task3 = sts.fork(() -> 3);
>              var task4 = sts.fork(() -> 4);
>              sts.join();
>              System.out.println(sts.result());  // 1 <--- ???
>          }
>
> This does not work because ShutdownOnSuccess uses shutdown()
Sure, but this is not how SOS (or SOF) is intended to be used.



>   and shutdown() is an event global to a scope, not an event which is local to one of the call to join().
>
> So being calling several join() inside a scope only works with a plain StructuredTaskScope but not with a ShutdownOnSuccess or a ShutdownOnFailure.
> It's even worth than that, the exact semantics depend on if the subclasses actually call shutdown which depends if the individual task threads succeed or not, so it's a runtime condition, not one that can be predicted just taking a look to the code apart in contrived examples as the one above.
>
> I think this semantics is confusing, because the semantics of join() is not the same depending on the subclass used.
> To fix that, there are two choices, either being able to call only one join() or shutdown() to works multiple times.
We need to decide whether allowing multiple rounds of forking+join is 
useful or not. At one point Paul suggested it added or allowed for too 
much complexity but we decide to kick it down the road to get more 
feedback first. So far I don't think anyone has showed examples that use it.

-Alan





More information about the loom-dev mailing list