< prev index next >

src/java.base/share/classes/java/lang/ScopedValue.java

Print this page

   1 /*
   2  * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2020, 2022, Red Hat Inc.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

  47  *
  48  * <p> In the Java programming language, data is usually passed to a method by means of a
  49  * method parameter. The data may need to be passed through a sequence of many methods to
  50  * get to the method that makes use of the data. Every method in the sequence of calls
  51  * needs to declare the parameter and every method has access to the data.
  52  * {@code ScopedValue} provides a means to pass data to a faraway method (typically a
  53  * <em>callback</em>) without using method parameters. In effect, a {@code ScopedValue}
  54  * is an <em>implicit method parameter</em>. It is "as if" every method in a sequence of
  55  * calls has an additional parameter. None of the methods declare the parameter and only
  56  * the methods that have access to the {@code ScopedValue} object can access its value
  57  * (the data). {@code ScopedValue} makes it possible to securely pass data from a
  58  * <em>caller</em> to a faraway <em>callee</em> through a sequence of intermediate methods
  59  * that do not declare a parameter for the data and have no access to the data.
  60  *
  61  * <p> The {@code ScopedValue} API works by executing a method with a {@code ScopedValue}
  62  * object <em>bound</em> to some value for the bounded period of execution of a method.
  63  * The method may invoke another method, which in turn may invoke another. The unfolding
  64  * execution of the methods define a <em>dynamic scope</em>. Code in these methods with
  65  * access to the {@code ScopedValue} object may read its value. The {@code ScopedValue}
  66  * object reverts to being <em>unbound</em> when the original method completes normally or
  67  * with an exception. The {@code ScopedValue} API supports executing a {@link Runnable#run()
  68  * Runnable.run}, {@link Callable#call() Callable.call}, or {@link Supplier#get() Supplier.get}
  69  * method with a {@code ScopedValue} bound to a value.
  70  *
  71  * <p> Consider the following example with a scoped value "{@code NAME}" bound to the value
  72  * "{@code duke}" for the execution of a {@code run} method. The {@code run} method, in
  73  * turn, invokes {@code doSomething}.
  74  * {@snippet lang=java :
  75  *     // @link substring="newInstance" target="#newInstance" :
  76  *     private static final ScopedValue<String> NAME = ScopedValue.newInstance();
  77  *
  78  *     // @link substring="runWhere" target="#runWhere" :
  79  *     ScopedValue.runWhere(NAME, "duke", () -> doSomething());
  80  * }
  81  * Code executed directly or indirectly by {@code doSomething}, with access to the field
  82  * {@code NAME}, can invoke {@code NAME.get()} to read the value "{@code duke}". {@code
  83  * NAME} is bound while executing the {@code run} method. It reverts to being unbound when
  84  * the {@code run} method completes.
  85  *
  86  * <p> The example using {@code runWhere} invokes a method that does not return a result.
  87  * The {@link #callWhere(ScopedValue, Object, Callable) callWhere} and {@link
  88  * #getWhere(ScopedValue, Object, Supplier) getWhere} can be used to invoke a method that
  89  * returns a result.
  90  * In addition, {@code ScopedValue} defines the {@link #where(ScopedValue, Object)} method
  91  * for cases where multiple mappings (of {@code ScopedValue} to value) are accumulated
  92  * in advance of calling a method with all {@code ScopedValue}s bound to their value.
  93  *
  94  * <h2>Bindings are per-thread</h2>
  95  *
  96  * A {@code ScopedValue} binding to a value is per-thread. Invoking {@code xxxWhere}
  97  * executes a method with a {@code ScopedValue} bound to a value for the current thread.
  98  * The {@link #get() get} method returns the value bound for the current thread.
  99  *
 100  * <p> In the example, if code executed by one thread invokes this:
 101  * {@snippet lang=java :
 102  *     ScopedValue.runWhere(NAME, "duke1", () -> doSomething());
 103  * }
 104  * and code executed by another thread invokes:
 105  * {@snippet lang=java :
 106  *     ScopedValue.runWhere(NAME, "duke2", () -> doSomething());
 107  * }
 108  * then code in {@code doSomething} (or any method that it calls) invoking {@code NAME.get()}
 109  * will read the value "{@code duke1}" or "{@code duke2}", depending on which thread is

 274             int bits = key.bitmask();
 275             for (Snapshot snapshot = this;
 276                  containsAll(snapshot.bitmask, bits);
 277                  snapshot = snapshot.prev) {
 278                 for (Carrier carrier = snapshot.bindings;
 279                      carrier != null && containsAll(carrier.bitmask, bits);
 280                      carrier = carrier.prev) {
 281                     if (carrier.getKey() == key) {
 282                         Object value = carrier.get();
 283                         return value;
 284                     }
 285                 }
 286             }
 287             return NIL;
 288         }
 289     }
 290 
 291     /**
 292      * A mapping of scoped values, as <em>keys</em>, to values.
 293      *
 294      * <p> A {@code Carrier} is used to accumulate mappings so that an operation (a
 295      * {@link Runnable} or {@link Callable}) can be executed with all scoped values in the
 296      * mapping bound to values. The following example runs an operation with {@code k1}
 297      * bound (or rebound) to {@code v1}, and {@code k2} bound (or rebound) to {@code v2}.

 298      * {@snippet lang=java :
 299      *     // @link substring="where" target="#where(ScopedValue, Object)" :
 300      *     ScopedValue.where(k1, v1).where(k2, v2).run(() -> ... );
 301      * }
 302      *
 303      * <p> A {@code Carrier} is immutable and thread-safe. The {@link
 304      * #where(ScopedValue, Object) where} method returns a new {@code Carrier} object,
 305      * it does not mutate an existing mapping.
 306      *
 307      * <p> Unless otherwise specified, passing a {@code null} argument to a method in
 308      * this class will cause a {@link NullPointerException} to be thrown.
 309      *
 310      * @since 21
 311      */
 312     @PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
 313     public static final class Carrier {
 314         // Bit masks: a 1 in postion n indicates that this set of bound values
 315         // hits that slot in the cache.
 316         final int bitmask;
 317         final ScopedValue<?> key;
 318         final Object value;
 319         final Carrier prev;
 320 

 366         ScopedValue<?> getKey() {
 367             return key;
 368         }
 369 
 370         /**
 371          * Returns the value of a {@link ScopedValue} in this mapping.
 372          *
 373          * @param key the {@code ScopedValue} key
 374          * @param <T> the type of the value
 375          * @return the value
 376          * @throws NoSuchElementException if the key is not present in this mapping
 377          */
 378         @SuppressWarnings("unchecked")
 379         public <T> T get(ScopedValue<T> key) {
 380             var bits = key.bitmask();
 381             for (Carrier carrier = this;
 382                  carrier != null && containsAll(carrier.bitmask, bits);
 383                  carrier = carrier.prev) {
 384                 if (carrier.getKey() == key) {
 385                     Object value = carrier.get();
 386                     return (T)value;
 387                 }
 388             }
 389             throw new NoSuchElementException();
 390         }
 391 
 392         /**
 393          * Calls a value-returning operation with each scoped value in this mapping bound
 394          * to its value in the current thread.
 395          * When the operation completes (normally or with an exception), each scoped value
 396          * in the mapping will revert to being unbound, or revert to its previous value
 397          * when previously bound, in the current thread. If {@code op} completes with an
 398          * exception then it propagated by this method.
 399          *
 400          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 401          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 402          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 403          * as a <em>structure violation</em> when the operation completes (normally or with an
 404          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 405          * is closed and {@link StructureViolationException} is thrown.
 406          *
 407          * @param op the operation to run
 408          * @param <R> the type of the result of the operation
 409          * @return the result
 410          * @throws StructureViolationException if a structure violation is detected
 411          * @throws Exception if {@code op} completes with an exception
 412          * @see ScopedValue#callWhere(ScopedValue, Object, Callable)
 413          */
 414         public <R> R call(Callable<? extends R> op) throws Exception {
 415             Objects.requireNonNull(op);
 416             Cache.invalidate(bitmask);
 417             var prevSnapshot = scopedValueBindings();
 418             var newSnapshot = new Snapshot(this, prevSnapshot);
 419             return runWith(newSnapshot, op);
 420         }
 421 
 422         /**
 423          * Invokes a supplier of results with each scoped value in this mapping bound
 424          * to its value in the current thread.
 425          * When the operation completes (normally or with an exception), each scoped value
 426          * in the mapping will revert to being unbound, or revert to its previous value
 427          * when previously bound, in the current thread. If {@code op} completes with an
 428          * exception then it propagated by this method.
 429          *
 430          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 431          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 432          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 433          * as a <em>structure violation</em> when the operation completes (normally or with an
 434          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 435          * is closed and {@link StructureViolationException} is thrown.
 436          *
 437          * @param op the operation to run
 438          * @param <R> the type of the result of the operation
 439          * @return the result
 440          * @throws StructureViolationException if a structure violation is detected
 441          * @see ScopedValue#getWhere(ScopedValue, Object, Supplier)
 442          */
 443         public <R> R get(Supplier<? extends R> op) {
 444             Objects.requireNonNull(op);
 445             Cache.invalidate(bitmask);
 446             var prevSnapshot = scopedValueBindings();
 447             var newSnapshot = new Snapshot(this, prevSnapshot);
 448             return runWith(newSnapshot, new CallableAdapter<R>(op));
 449         }
 450 
 451         // A lightweight adapter from Supplier to Callable. This is
 452         // used here to create the Callable which is passed to
 453         // Carrier#call() in this thread because it needs neither
 454         // runtime bytecode generation nor any release fencing.
 455         private static final class CallableAdapter<V> implements Callable<V> {
 456             private /*non-final*/ Supplier<? extends V> s;
 457             CallableAdapter(Supplier<? extends V> s) {
 458                 this.s = s;
 459             }
 460             public V call() {
 461                 return s.get();
 462             }
 463         }

 485 
 486         /**
 487          * Runs an operation with each scoped value in this mapping bound to its value
 488          * in the current thread.
 489          * When the operation completes (normally or with an exception), each scoped value
 490          * in the mapping will revert to being unbound, or revert to its previous value
 491          * when previously bound, in the current thread. If {@code op} completes with an
 492          * exception then it propagated by this method.
 493          *
 494          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 495          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 496          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 497          * as a <em>structure violation</em> when the operation completes (normally or with an
 498          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 499          * is closed and {@link StructureViolationException} is thrown.
 500          *
 501          * @param op the operation to run
 502          * @throws StructureViolationException if a structure violation is detected
 503          * @see ScopedValue#runWhere(ScopedValue, Object, Runnable)
 504          */
 505         public void run(Runnable op) {
 506             Objects.requireNonNull(op);
 507             Cache.invalidate(bitmask);
 508             var prevSnapshot = scopedValueBindings();
 509             var newSnapshot = new Snapshot(this, prevSnapshot);
 510             runWith(newSnapshot, op);
 511         }
 512 
 513         /**
 514          * Execute the action with a set of {@code ScopedValue} bindings.
 515          *
 516          * The VM recognizes this method as special, so any changes to the
 517          * name or signature require corresponding changes in
 518          * JVM_FindScopedValueBindings().
 519          */
 520         @Hidden
 521         @ForceInline
 522         private void runWith(Snapshot newSnapshot, Runnable op) {
 523             try {
 524                 Thread.setScopedValueBindings(newSnapshot);
 525                 Thread.ensureMaterializedForStackWalk(newSnapshot);
 526                 ScopedValueContainer.run(op);
 527             } finally {
 528                 Reference.reachabilityFence(newSnapshot);
 529                 Thread.setScopedValueBindings(newSnapshot.prev);
 530                 Cache.invalidate(bitmask);
 531             }
 532         }
 533     }
 534 
 535     /**
 536      * Creates a new {@code Carrier} with a single mapping of a {@code ScopedValue}
 537      * <em>key</em> to a value. The {@code Carrier} can be used to accumulate mappings so
 538      * that an operation can be executed with all scoped values in the mapping bound to
 539      * values. The following example runs an operation with {@code k1} bound (or rebound)
 540      * to {@code v1}, and {@code k2} bound (or rebound) to {@code v2}.
 541      * {@snippet lang=java :
 542      *     // @link substring="run" target="Carrier#run(Runnable)" :
 543      *     ScopedValue.where(k1, v1).where(k2, v2).run(() -> ... );
 544      * }
 545      *
 546      * @param key the {@code ScopedValue} key
 547      * @param value the value, can be {@code null}
 548      * @param <T> the type of the value
 549      * @return a new {@code Carrier} with a single mapping
 550      */
 551     public static <T> Carrier where(ScopedValue<T> key, T value) {
 552         return Carrier.of(key, value);
 553     }
 554 
 555     /**
 556      * Calls a value-returning operation with a {@code ScopedValue} bound to a value
 557      * in the current thread. When the operation completes (normally or with an
 558      * exception), the {@code ScopedValue} will revert to being unbound, or revert to
 559      * its previous value when previously bound, in the current thread. If {@code op}
 560      * completes with an exception then it propagated by this method.
 561      *
 562      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 563      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 564      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 565      * as a <em>structure violation</em> when the operation completes (normally or with an
 566      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 567      * is closed and {@link StructureViolationException} is thrown.
 568      *
 569      * @implNote
 570      * This method is implemented to be equivalent to:
 571      * {@snippet lang=java :
 572      *     // @link substring="call" target="Carrier#call(Callable)" :
 573      *     ScopedValue.where(key, value).call(op);
 574      * }
 575      *
 576      * @param key the {@code ScopedValue} key
 577      * @param value the value, can be {@code null}
 578      * @param <T> the type of the value
 579      * @param <R> the result type
 580      * @param op the operation to call
 581      * @return the result
 582      * @throws StructureViolationException if a structure violation is detected
 583      * @throws Exception if the operation completes with an exception
 584      */
 585     public static <T, R> R callWhere(ScopedValue<T> key,
 586                                      T value,
 587                                      Callable<? extends R> op) throws Exception {
 588         return where(key, value).call(op);
 589     }
 590 




























 591     /**
 592      * Invokes a supplier of results with a {@code ScopedValue} bound to a value
 593      * in the current thread. When the operation completes (normally or with an
 594      * exception), the {@code ScopedValue} will revert to being unbound, or revert to
 595      * its previous value when previously bound, in the current thread. If {@code op}
 596      * completes with an exception then it propagated by this method.
 597      *
 598      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 599      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 600      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 601      * as a <em>structure violation</em> when the operation completes (normally or with an
 602      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 603      * is closed and {@link StructureViolationException} is thrown.
 604      *
 605      * @implNote
 606      * This method is implemented to be equivalent to:
 607      * {@snippet lang=java :
 608      *     // @link substring="get" target="Carrier#get(Supplier)" :
 609      *     ScopedValue.where(key, value).get(op);
 610      * }
 611      *
 612      * @param key the {@code ScopedValue} key
 613      * @param value the value, can be {@code null}
 614      * @param <T> the type of the value
 615      * @param <R> the result type
 616      * @param op the operation to call
 617      * @return the result
 618      * @throws StructureViolationException if a structure violation is detected
 619      */
 620     public static <T, R> R getWhere(ScopedValue<T> key,
 621                                     T value,
 622                                     Supplier<? extends R> op) {
 623         return where(key, value).get(op);
 624     }
 625 


























 626     /**
 627      * Run an operation with a {@code ScopedValue} bound to a value in the current
 628      * thread. When the operation completes (normally or with an exception), the
 629      * {@code ScopedValue} will revert to being unbound, or revert to its previous value
 630      * when previously bound, in the current thread. If {@code op} completes with an
 631      * exception then it propagated by this method.
 632      *
 633      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 634      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 635      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 636      * as a <em>structure violation</em> when the operation completes (normally or with an
 637      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 638      * is closed and {@link StructureViolationException} is thrown.
 639      *
 640      * @implNote
 641      * This method is implemented to be equivalent to:
 642      * {@snippet lang=java :
 643      *     // @link substring="run" target="Carrier#run(Runnable)" :
 644      *     ScopedValue.where(key, value).run(op);
 645      * }
 646      *
 647      * @param key the {@code ScopedValue} key
 648      * @param value the value, can be {@code null}
 649      * @param <T> the type of the value
 650      * @param op the operation to call
 651      * @throws StructureViolationException if a structure violation is detected
 652      */
 653     public static <T> void runWhere(ScopedValue<T> key, T value, Runnable op) {
 654         where(key, value).run(op);
 655     }
 656 
























 657     private ScopedValue() {
 658         this.hash = generateKey();
 659     }
 660 
 661     /**
 662      * Creates a scoped value that is initially unbound for all threads.
 663      *
 664      * @param <T> the type of the value
 665      * @return a new {@code ScopedValue}
 666      */
 667     public static <T> ScopedValue<T> newInstance() {
 668         return new ScopedValue<T>();
 669     }
 670 
 671     /**
 672      * {@return the value of the scoped value if bound in the current thread}
 673      *
 674      * @throws NoSuchElementException if the scoped value is not bound
 675      */
 676     @ForceInline

   1 /*
   2  * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2020, 2022, Red Hat Inc.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

  47  *
  48  * <p> In the Java programming language, data is usually passed to a method by means of a
  49  * method parameter. The data may need to be passed through a sequence of many methods to
  50  * get to the method that makes use of the data. Every method in the sequence of calls
  51  * needs to declare the parameter and every method has access to the data.
  52  * {@code ScopedValue} provides a means to pass data to a faraway method (typically a
  53  * <em>callback</em>) without using method parameters. In effect, a {@code ScopedValue}
  54  * is an <em>implicit method parameter</em>. It is "as if" every method in a sequence of
  55  * calls has an additional parameter. None of the methods declare the parameter and only
  56  * the methods that have access to the {@code ScopedValue} object can access its value
  57  * (the data). {@code ScopedValue} makes it possible to securely pass data from a
  58  * <em>caller</em> to a faraway <em>callee</em> through a sequence of intermediate methods
  59  * that do not declare a parameter for the data and have no access to the data.
  60  *
  61  * <p> The {@code ScopedValue} API works by executing a method with a {@code ScopedValue}
  62  * object <em>bound</em> to some value for the bounded period of execution of a method.
  63  * The method may invoke another method, which in turn may invoke another. The unfolding
  64  * execution of the methods define a <em>dynamic scope</em>. Code in these methods with
  65  * access to the {@code ScopedValue} object may read its value. The {@code ScopedValue}
  66  * object reverts to being <em>unbound</em> when the original method completes normally or
  67  * with an exception. The {@code ScopedValue} API supports executing a {@link Runnable},
  68  * {@link Callable}, or {@link Supplier} with a {@code ScopedValue} bound to a value.

  69  *
  70  * <p> Consider the following example with a scoped value "{@code NAME}" bound to the value
  71  * "{@code duke}" for the execution of a {@code run} method. The {@code run} method, in
  72  * turn, invokes {@code doSomething}.
  73  * {@snippet lang=java :
  74  *     // @link substring="newInstance" target="#newInstance" :
  75  *     private static final ScopedValue<String> NAME = ScopedValue.newInstance();
  76  *
  77  *     // @link substring="runWhere" target="#runWhere(ScopedValue, Object, Runnable)" :
  78  *     ScopedValue.runWhere(NAME, "duke", () -> doSomething());
  79  * }
  80  * Code executed directly or indirectly by {@code doSomething}, with access to the field
  81  * {@code NAME}, can invoke {@code NAME.get()} to read the value "{@code duke}". {@code
  82  * NAME} is bound while executing the {@code run} method. It reverts to being unbound when
  83  * the {@code run} method completes.
  84  *
  85  * <p> The example using {@code runWhere} invokes a method that does not return a result.
  86  * The {@link #callWhere(ScopedValue, Object, Callable) callWhere} and {@link
  87  * #getWhere(ScopedValue, Object, Supplier) getWhere} methods can be used to invoke a
  88  * method that returns a result.
  89  * In addition, {@code ScopedValue} defines the {@link #where(ScopedValue, Object)} method
  90  * for cases where multiple mappings (of {@code ScopedValue} to value) are accumulated
  91  * in advance of calling a method with all {@code ScopedValue}s bound to their value.
  92  *
  93  * <h2>Bindings are per-thread</h2>
  94  *
  95  * A {@code ScopedValue} binding to a value is per-thread. Invoking {@code xxxWhere}
  96  * executes a method with a {@code ScopedValue} bound to a value for the current thread.
  97  * The {@link #get() get} method returns the value bound for the current thread.
  98  *
  99  * <p> In the example, if code executed by one thread invokes this:
 100  * {@snippet lang=java :
 101  *     ScopedValue.runWhere(NAME, "duke1", () -> doSomething());
 102  * }
 103  * and code executed by another thread invokes:
 104  * {@snippet lang=java :
 105  *     ScopedValue.runWhere(NAME, "duke2", () -> doSomething());
 106  * }
 107  * then code in {@code doSomething} (or any method that it calls) invoking {@code NAME.get()}
 108  * will read the value "{@code duke1}" or "{@code duke2}", depending on which thread is

 273             int bits = key.bitmask();
 274             for (Snapshot snapshot = this;
 275                  containsAll(snapshot.bitmask, bits);
 276                  snapshot = snapshot.prev) {
 277                 for (Carrier carrier = snapshot.bindings;
 278                      carrier != null && containsAll(carrier.bitmask, bits);
 279                      carrier = carrier.prev) {
 280                     if (carrier.getKey() == key) {
 281                         Object value = carrier.get();
 282                         return value;
 283                     }
 284                 }
 285             }
 286             return NIL;
 287         }
 288     }
 289 
 290     /**
 291      * A mapping of scoped values, as <em>keys</em>, to values.
 292      *
 293      * <p> A {@code Carrier} is used to accumulate mappings so that an operation (a {@link
 294      * Runnable}, {@link Callable} or {@link Supplier}) can be executed with all scoped
 295      * values in the mapping bound to values. The following example runs an operation with
 296      * {@code k1} bound (or rebound) to {@code v1}, and {@code k2} bound (or rebound) to
 297      * {@code v2}.
 298      * {@snippet lang=java :
 299      *     ScopedValue.runWhere(ScopedValue.where(k1, v1).where(k2, v2), () -> ... );

 300      * }
 301      *
 302      * <p> A {@code Carrier} is immutable and thread-safe. The {@link
 303      * #where(ScopedValue, Object) where} method returns a new {@code Carrier} object,
 304      * it does not mutate an existing mapping.
 305      *
 306      * <p> Unless otherwise specified, passing a {@code null} argument to a method in
 307      * this class will cause a {@link NullPointerException} to be thrown.
 308      *
 309      * @since 21
 310      */
 311     @PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
 312     public static final class Carrier {
 313         // Bit masks: a 1 in postion n indicates that this set of bound values
 314         // hits that slot in the cache.
 315         final int bitmask;
 316         final ScopedValue<?> key;
 317         final Object value;
 318         final Carrier prev;
 319 

 365         ScopedValue<?> getKey() {
 366             return key;
 367         }
 368 
 369         /**
 370          * Returns the value of a {@link ScopedValue} in this mapping.
 371          *
 372          * @param key the {@code ScopedValue} key
 373          * @param <T> the type of the value
 374          * @return the value
 375          * @throws NoSuchElementException if the key is not present in this mapping
 376          */
 377         @SuppressWarnings("unchecked")
 378         public <T> T get(ScopedValue<T> key) {
 379             var bits = key.bitmask();
 380             for (Carrier carrier = this;
 381                  carrier != null && containsAll(carrier.bitmask, bits);
 382                  carrier = carrier.prev) {
 383                 if (carrier.getKey() == key) {
 384                     Object value = carrier.get();
 385                     return (T) value;
 386                 }
 387             }
 388             throw new NoSuchElementException();
 389         }
 390 
 391         /**
 392          * Calls a value-returning operation with each scoped value in this mapping bound
 393          * to its value in the current thread.
 394          * When the operation completes (normally or with an exception), each scoped value
 395          * in the mapping will revert to being unbound, or revert to its previous value
 396          * when previously bound, in the current thread. If {@code op} completes with an
 397          * exception then it propagated by this method.
 398          *
 399          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 400          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 401          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 402          * as a <em>structure violation</em> when the operation completes (normally or with an
 403          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 404          * is closed and {@link StructureViolationException} is thrown.
 405          *
 406          * @param op the operation to run
 407          * @param <R> the type of the result of the operation
 408          * @return the result
 409          * @throws StructureViolationException if a structure violation is detected
 410          * @throws Exception if {@code op} completes with an exception
 411          * @see ScopedValue#callWhere(ScopedValue, Object, Callable)
 412          */
 413         <R> R call(Callable<? extends R> op) throws Exception {
 414             Objects.requireNonNull(op);
 415             Cache.invalidate(bitmask);
 416             var prevSnapshot = scopedValueBindings();
 417             var newSnapshot = new Snapshot(this, prevSnapshot);
 418             return runWith(newSnapshot, op);
 419         }
 420 
 421         /**
 422          * Invokes a supplier of results with each scoped value in this mapping bound
 423          * to its value in the current thread.
 424          * When the operation completes (normally or with an exception), each scoped value
 425          * in the mapping will revert to being unbound, or revert to its previous value
 426          * when previously bound, in the current thread. If {@code op} completes with an
 427          * exception then it propagated by this method.
 428          *
 429          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 430          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 431          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 432          * as a <em>structure violation</em> when the operation completes (normally or with an
 433          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 434          * is closed and {@link StructureViolationException} is thrown.
 435          *
 436          * @param op the operation to run
 437          * @param <R> the type of the result of the operation
 438          * @return the result
 439          * @throws StructureViolationException if a structure violation is detected
 440          * @see ScopedValue#getWhere(ScopedValue, Object, Supplier)
 441          */
 442         <R> R get(Supplier<? extends R> op) {
 443             Objects.requireNonNull(op);
 444             Cache.invalidate(bitmask);
 445             var prevSnapshot = scopedValueBindings();
 446             var newSnapshot = new Snapshot(this, prevSnapshot);
 447             return runWith(newSnapshot, new CallableAdapter<R>(op));
 448         }
 449 
 450         // A lightweight adapter from Supplier to Callable. This is
 451         // used here to create the Callable which is passed to
 452         // Carrier#call() in this thread because it needs neither
 453         // runtime bytecode generation nor any release fencing.
 454         private static final class CallableAdapter<V> implements Callable<V> {
 455             private /*non-final*/ Supplier<? extends V> s;
 456             CallableAdapter(Supplier<? extends V> s) {
 457                 this.s = s;
 458             }
 459             public V call() {
 460                 return s.get();
 461             }
 462         }

 484 
 485         /**
 486          * Runs an operation with each scoped value in this mapping bound to its value
 487          * in the current thread.
 488          * When the operation completes (normally or with an exception), each scoped value
 489          * in the mapping will revert to being unbound, or revert to its previous value
 490          * when previously bound, in the current thread. If {@code op} completes with an
 491          * exception then it propagated by this method.
 492          *
 493          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 494          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 495          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 496          * as a <em>structure violation</em> when the operation completes (normally or with an
 497          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 498          * is closed and {@link StructureViolationException} is thrown.
 499          *
 500          * @param op the operation to run
 501          * @throws StructureViolationException if a structure violation is detected
 502          * @see ScopedValue#runWhere(ScopedValue, Object, Runnable)
 503          */
 504         void run(Runnable op) {
 505             Objects.requireNonNull(op);
 506             Cache.invalidate(bitmask);
 507             var prevSnapshot = scopedValueBindings();
 508             var newSnapshot = new Snapshot(this, prevSnapshot);
 509             runWith(newSnapshot, op);
 510         }
 511 
 512         /**
 513          * Execute the action with a set of {@code ScopedValue} bindings.
 514          *
 515          * The VM recognizes this method as special, so any changes to the
 516          * name or signature require corresponding changes in
 517          * JVM_FindScopedValueBindings().
 518          */
 519         @Hidden
 520         @ForceInline
 521         private void runWith(Snapshot newSnapshot, Runnable op) {
 522             try {
 523                 Thread.setScopedValueBindings(newSnapshot);
 524                 Thread.ensureMaterializedForStackWalk(newSnapshot);
 525                 ScopedValueContainer.run(op);
 526             } finally {
 527                 Reference.reachabilityFence(newSnapshot);
 528                 Thread.setScopedValueBindings(newSnapshot.prev);
 529                 Cache.invalidate(bitmask);
 530             }
 531         }
 532     }
 533 
 534     /**
 535      * Creates a new {@code Carrier} with a single mapping of a {@code ScopedValue}
 536      * <em>key</em> to a value. The {@code Carrier} can be used to accumulate mappings so
 537      * that an operation can be executed with all scoped values in the mapping bound to
 538      * values. The following example runs an operation with {@code k1} bound (or rebound)
 539      * to {@code v1}, and {@code k2} bound (or rebound) to {@code v2}.
 540      * {@snippet lang=java :
 541      *     // @link substring="runWhere" target="#runWhere(Carrier, Runnable)" :
 542      *     ScopedValue.runWhere(ScopedValue.where(k1, v1).where(k2, v2), () -> ... );
 543      * }
 544      *
 545      * @param key the {@code ScopedValue} key
 546      * @param value the value, can be {@code null}
 547      * @param <T> the type of the value
 548      * @return a new {@code Carrier} with a single mapping
 549      */
 550     public static <T> Carrier where(ScopedValue<T> key, T value) {
 551         return Carrier.of(key, value);
 552     }
 553 
 554     /**
 555      * Calls a value-returning operation with a {@code ScopedValue} bound to a value
 556      * in the current thread. When the operation completes (normally or with an
 557      * exception), the {@code ScopedValue} will revert to being unbound, or revert to
 558      * its previous value when previously bound, in the current thread. If {@code op}
 559      * completes with an exception then it propagated by this method.
 560      *
 561      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 562      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 563      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 564      * as a <em>structure violation</em> when the operation completes (normally or with an
 565      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 566      * is closed and {@link StructureViolationException} is thrown.
 567      *







 568      * @param key the {@code ScopedValue} key
 569      * @param value the value, can be {@code null}
 570      * @param <T> the type of the value
 571      * @param <R> the result type
 572      * @param op the operation to call
 573      * @return the result
 574      * @throws StructureViolationException if a structure violation is detected
 575      * @throws Exception if the operation completes with an exception
 576      */
 577     public static <T, R> R callWhere(ScopedValue<T> key,
 578                                      T value,
 579                                      Callable<? extends R> op) throws Exception {
 580         return where(key, value).call(op);
 581     }
 582 
 583     /**
 584      * Calls a value-returning operation with each scoped value in the given mapping bound
 585      * to its value in the current thread.
 586      * When the operation completes (normally or with an exception), each scoped value
 587      * in the mapping will revert to being unbound, or revert to its previous value
 588      * when previously bound, in the current thread. If {@code op} completes with an
 589      * exception then it propagated by this method.
 590      *
 591      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 592      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 593      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 594      * as a <em>structure violation</em> when the operation completes (normally or with an
 595      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 596      * is closed and {@link StructureViolationException} is thrown.
 597      *
 598      * @param carrier the mapping of scoped values, as keys, to values
 599      * @param op the operation to run
 600      * @return the result
 601      * @param <R> the result type
 602      * @throws StructureViolationException if a structure violation is detected
 603      * @throws Exception if the operation completes with an exception
 604      * @since 23
 605      */
 606     public static <R> R callWhere(Carrier carrier,
 607                                   Callable<? extends R> op) throws Exception {
 608         return carrier.call(op);
 609     }
 610 
 611     /**
 612      * Invokes a supplier of results with a {@code ScopedValue} bound to a value
 613      * in the current thread. When the operation completes (normally or with an
 614      * exception), the {@code ScopedValue} will revert to being unbound, or revert to
 615      * its previous value when previously bound, in the current thread. If {@code op}
 616      * completes with an exception then it propagated by this method.
 617      *
 618      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 619      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 620      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 621      * as a <em>structure violation</em> when the operation completes (normally or with an
 622      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 623      * is closed and {@link StructureViolationException} is thrown.
 624      *







 625      * @param key the {@code ScopedValue} key
 626      * @param value the value, can be {@code null}
 627      * @param <T> the type of the value
 628      * @param <R> the result type
 629      * @param op the operation to call
 630      * @return the result
 631      * @throws StructureViolationException if a structure violation is detected
 632      */
 633     public static <T, R> R getWhere(ScopedValue<T> key,
 634                                     T value,
 635                                     Supplier<? extends R> op) {
 636         return where(key, value).get(op);
 637     }
 638 
 639     /**
 640      * Invokes a supplier of results with each scoped value in the given mapping bound
 641      * to its value in the current thread.
 642      * When the operation completes (normally or with an exception), each scoped value
 643      * in the mapping will revert to being unbound, or revert to its previous value
 644      * when previously bound, in the current thread. If {@code op} completes with an
 645      * exception then it propagated by this method.
 646      *
 647      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 648      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 649      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 650      * as a <em>structure violation</em> when the operation completes (normally or with an
 651      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 652      * is closed and {@link StructureViolationException} is thrown.
 653      *
 654      * @param carrier the mapping of scoped values, as keys, to values
 655      * @param op the operation to run
 656      * @return the result
 657      * @param <R> the result type
 658      * @throws StructureViolationException if a structure violation is detected
 659      * @since 23
 660      */
 661     public static <R> R getWhere(Carrier carrier, Supplier<? extends R> op) {
 662         return carrier.get(op);
 663     }
 664 
 665     /**
 666      * Run an operation with a {@code ScopedValue} bound to a value in the current
 667      * thread. When the operation completes (normally or with an exception), the
 668      * {@code ScopedValue} will revert to being unbound, or revert to its previous value
 669      * when previously bound, in the current thread. If {@code op} completes with an
 670      * exception then it propagated by this method.
 671      *
 672      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 673      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 674      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 675      * as a <em>structure violation</em> when the operation completes (normally or with an
 676      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 677      * is closed and {@link StructureViolationException} is thrown.
 678      *







 679      * @param key the {@code ScopedValue} key
 680      * @param value the value, can be {@code null}
 681      * @param <T> the type of the value
 682      * @param op the operation to call
 683      * @throws StructureViolationException if a structure violation is detected
 684      */
 685     public static <T> void runWhere(ScopedValue<T> key, T value, Runnable op) {
 686         where(key, value).run(op);
 687     }
 688 
 689     /**
 690      * Runs an operation with each scoped value in the given mapping bound to its value
 691      * in the current thread.
 692      * When the operation completes (normally or with an exception), each scoped value
 693      * in the mapping will revert to being unbound, or revert to its previous value
 694      * when previously bound, in the current thread. If {@code op} completes with an
 695      * exception then it propagated by this method.
 696      *
 697      * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
 698      * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
 699      * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
 700      * as a <em>structure violation</em> when the operation completes (normally or with an
 701      * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
 702      * is closed and {@link StructureViolationException} is thrown.
 703      *
 704      * @param carrier the mapping of scoped values, as keys, to values
 705      * @param op the operation to run
 706      * @throws StructureViolationException if a structure violation is detected
 707      * @since 23
 708      */
 709     public static void runWhere(Carrier carrier, Runnable op) {
 710         carrier.run(op);
 711     }
 712 
 713     private ScopedValue() {
 714         this.hash = generateKey();
 715     }
 716 
 717     /**
 718      * Creates a scoped value that is initially unbound for all threads.
 719      *
 720      * @param <T> the type of the value
 721      * @return a new {@code ScopedValue}
 722      */
 723     public static <T> ScopedValue<T> newInstance() {
 724         return new ScopedValue<T>();
 725     }
 726 
 727     /**
 728      * {@return the value of the scoped value if bound in the current thread}
 729      *
 730      * @throws NoSuchElementException if the scoped value is not bound
 731      */
 732     @ForceInline
< prev index next >