<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.apple-converted-space
        {mso-style-name:apple-converted-space;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:212427946;
        mso-list-template-ids:843761692;}
@list l0:level1
        {mso-level-start-at:2;
        mso-level-tab-stop:36.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:72.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l1
        {mso-list-id:769739963;
        mso-list-template-ids:-1029690992;}
@list l1:level1
        {mso-level-start-at:3;
        mso-level-tab-stop:36.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l1:level2
        {mso-level-start-at:3;
        mso-level-number-format:alpha-lower;
        mso-level-tab-stop:72.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2
        {mso-list-id:2140107300;
        mso-list-template-ids:591450178;}
@list l2:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:72.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l1:level2 lfo4
        {mso-level-start-at:1;}
@list l1:level2 lfo5
        {mso-level-start-at:1;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-CA link=blue vlink=purple style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal><span style='mso-fareast-language:EN-US'>Thanks for that clarity, Ron.<o:p></o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'>So, as always, use existing best practices to make sure that tasks and subtasks are robust in handling cancellation, interrupts, exceptions, etc.<o:p></o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'>Loom does not bring any new magic here…<o:p></o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'>Cheers, Eric<o:p></o:p></span></p><p class=MsoNormal><span style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US>From:</span></b><span lang=EN-US> Ron Pressler <ron.pressler@oracle.com> <br><b>Sent:</b> July 27, 2022 10:17 AM<br><b>To:</b> Eric Kolotyluk <eric@kolotyluk.net><br><b>Cc:</b> loom-dev@openjdk.java.net<br><b>Subject:</b> Re: Unclear on close()<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal><br><br><o:p></o:p></p><blockquote style='margin-top:5.0pt;margin-bottom:5.0pt'><div><p class=MsoNormal>On 27 Jul 2022, at 17:35, <a href="mailto:eric@kolotyluk.net">eric@kolotyluk.net</a> wrote:<o:p></o:p></p></div><div><div><p class=MsoNormal> <o:p></o:p></p></div><ol style='margin-top:0cm' start=1 type=1><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l2 level1 lfo1'>Is there any scenario where close() waits forever?<o:p></o:p></li></ol><ol style='margin-top:0cm' start=1 type=1><ol style='margin-top:0cm' start=1 type=a><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l2 level2 lfo1'>Where it is implicit in this try block.<o:p></o:p></li><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l2 level2 lfo1'>I can imagine scenarios where subtasks don’t cancel properly or respond correctly to interrupts.<o:p></o:p></li></ol></ol></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>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.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>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.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><blockquote style='margin-top:5.0pt;margin-bottom:5.0pt'><div><ol style='margin-top:0cm' start=2 type=1><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l0 level1 lfo2'>If there is, is there any programmatic way out of this?<o:p></o:p></li></ol><ol style='margin-top:0cm' start=2 type=1><ol style='margin-top:0cm' start=1 type=a><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l0 level2 lfo2'>Does the InterruptedException bypass close() and exit the try block?<o:p></o:p></li><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l0 level2 lfo2'>Is this guaranteed by the runtime?<o:p></o:p></li><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l0 level2 lfo2'>I assume it is, but I have made bad assumptions about the runtime before…<o:p></o:p></li></ol></ol></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>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.<o:p></o:p></p></div><p class=MsoNormal><br><br><o:p></o:p></p><blockquote style='margin-top:5.0pt;margin-bottom:5.0pt'><div><ol style='margin-top:0cm' start=3 type=1><ol style='margin-top:0cm' start=3 type=a><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l1 level2 lfo3'><o:p> </o:p></li></ol></ol><ol style='margin-top:0cm' start=4 type=1><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l1 level1 lfo3'>Personally, I would have thought that “<span style='font-size:10.0pt;font-family:"Courier New"'>scope.joinUntil(deadline);</span>” would guarantee this code exits the try block, but the documentation, as written, does not give me that confidence. There are two wait points…<o:p></o:p></li></ol><ol style='margin-top:0cm' start=4 type=1><ol style='margin-top:0cm' start=1 type=a><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l1 level2 lfo4'><span style='font-size:10.0pt;font-family:"Courier New"'>scope.joinUntil(deadline);</span><o:p></o:p></li><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l1 level2 lfo4'><span style='font-size:10.0pt;font-family:"Courier New"'>scope.close();<span class=apple-converted-space> </span></span><o:p></o:p></li></ol></ol><ol style='margin-top:0cm' start=5 type=1><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l1 level1 lfo4'>While this may not be ambiguous to others, it is to me.<o:p></o:p></li></ol><ol style='margin-top:0cm' start=5 type=1><ol style='margin-top:0cm' start=1 type=a><li class=MsoListParagraph style='margin-top:0cm;margin-bottom:0cm;mso-list:l1 level2 lfo5'>It would be nice if there was text that made this more explicit.<o:p></o:p></li></ol></ol><div><p class=MsoNormal> <o:p></o:p></p></div><div><p class=MsoNormal>Cheers, Eric<o:p></o:p></p></div></div></blockquote></div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>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.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Whatever happens, close waits for all forked threads to fully terminate.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>— Ron<o:p></o:p></p></div></div></body></html>