<!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>