<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 11/07/2025 11:57, Nikita Bobko
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:60C1C447-F3A2-4064-B86C-96AD1523020D@jetbrains.com">
      <pre wrap="" class="moz-quote-pre">:

Who defines the lifetime? The current stack inside Carrier.run defines
the lifetime. Whilst the stack is alive, all so far bound ScopedValues
remain alive. StructuredTaskScope takes advantage of this fact. Whenever
users call StructuredTaskScope.join (and block the parent thread by
doing that), they effectively make sure that the stack will live long
enough, so that all ScopedValues could be safely accessed in child
virtual threads.

</pre>
    </blockquote>
    It's the close method (not join) that is specified to not continue
    until all threads forked in the scope have finished. Structure is
    enforced at runtime. There is a per-Thread scope stack: open is a
    push, close is pop. Same thing with ScopedValue where run (or call)
    does a push, executes the ops, then pops. Code executing in a thread
    can't pop out of order and can't terminate with a non-empty scope
    stack. <br>
    <br>
    -Alan<br>
  </body>
</html>