[External] : RE: Unclear on close()

Ron Pressler ron.pressler at oracle.com
Wed Jul 27 22:33:47 UTC 2022


That’s correct.

The kind of magic that would be required here would have to make the platform much more high-level.

On the other hand, some languages — Clojure maybe? — might be restrictive enough in their control of side-effects, or at least have sufficiently useful subsets that are restrictive enough, that they could consider having their compilers automatically emit interrupting checks into the bytecode they generate.

— Ron

On 27 Jul 2022, at 19:36, eric at kolotyluk.net<mailto:eric at kolotyluk.net> wrote:

Thanks for that clarity, Ron.

So, as always, use existing best practices to make sure that tasks and subtasks are robust in handling cancellation, interrupts, exceptions, etc.

Loom does not bring any new magic here…

Cheers, Eric

From: Ron Pressler <ron.pressler at oracle.com<mailto:ron.pressler at oracle.com>>
Sent: July 27, 2022 10:17 AM
To: Eric Kolotyluk <eric at kolotyluk.net<mailto:eric at kolotyluk.net>>
Cc: loom-dev at openjdk.java.net<mailto:loom-dev at openjdk.java.net>
Subject: Re: Unclear on close()




On 27 Jul 2022, at 17:35, eric at kolotyluk.net<mailto:eric at kolotyluk.net> wrote:


  1.  Is there any scenario where close() waits forever?

     *   Where it is implicit in this try block.
     *   I can imagine scenarios where subtasks don’t cancel properly or respond correctly to interrupts.


Yes, that could happen. It is a property of very general languages, like Java, and there’s no getting around it. It takes a very carefully-controlled language, like Erlang, to support the forceful (non-cooperative) termination of a thread, and even there things could go wrong unless some discipline is followed.

The core of the issue is that waiting for a thread to terminate is the least of your worries. It is more important to ensure that threads maintain your program’s logical invariants, and so we must ensure threads are terminated when they decide they’re ready. This requires their cooperation. So we can only ever *ask* for a thread to terminate; we can’t kill it in a way that safely maintains program invariants.


  1.  If there is, is there any programmatic way out of this?

     *   Does the InterruptedException bypass close() and exit the try block?
     *   Is this guaranteed by the runtime?
     *   I assume it is, but I have made bad assumptions about the runtime before…


An exception could not bypass the close if used in a try-with-resources block, but because we rely on try-with-resources, which is optional (i.e. you could neglect to use the construct altogether), there are ways to write code that doesn’t call close. The runtime would, currently, only detect that if this interferes with other things that rely on correct nesting of scopes. So, e.g. if you don’t close a scope but then close an enclosing scope, that will be detected.



     *

  1.  Personally, I would have thought that “scope.joinUntil(deadline);” would guarantee this code exits the try block, but the documentation, as written, does not give me that confidence. There are two wait points…

     *   scope.joinUntil(deadline);
     *   scope.close();

  1.  While this may not be ambiguous to others, it is to me.

     *   It would be nice if there was text that made this more explicit.


Cheers, Eric

close can only return after all threads have terminated (except, maybe, due to a VM error). join/joinUntil wait for forks to: 1. terminate OR 2. be cancelled due to shutdown OR 3. until the waiting thread is interrupted or the timeout expires.

Whatever happens, close waits for all forked threads to fully terminate.

— Ron

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20220727/c1b423a9/attachment-0001.htm>


More information about the loom-dev mailing list