mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-28 03:43:21 +00:00
8355022: Implement JEP 506: Scoped Values
Reviewed-by: liach, alanb
This commit is contained in:
parent
f02190bc30
commit
4e1878ca45
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Red Hat Inc.
|
||||
* Copyright (c) 2020, 2025, Red Hat Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,7 +34,6 @@ import java.util.concurrent.StructureViolationException;
|
||||
import java.util.function.Supplier;
|
||||
import jdk.internal.access.JavaUtilConcurrentTLRAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.javac.PreviewFeature;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.Hidden;
|
||||
import jdk.internal.vm.ScopedValueContainer;
|
||||
@ -237,9 +236,8 @@ import jdk.internal.vm.ScopedValueContainer;
|
||||
* have to be regenerated after a blocking operation.
|
||||
*
|
||||
* @param <T> the type of the value
|
||||
* @since 21
|
||||
* @since 25
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
|
||||
public final class ScopedValue<T> {
|
||||
private final int hash;
|
||||
|
||||
@ -310,9 +308,8 @@ public final class ScopedValue<T> {
|
||||
* <p> Unless otherwise specified, passing a {@code null} argument to a method in
|
||||
* this class will cause a {@link NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 21
|
||||
* @since 25
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
|
||||
public static final class Carrier {
|
||||
// Bit masks: a 1 in position n indicates that this set of bound values
|
||||
// hits that slot in the cache.
|
||||
@ -413,7 +410,6 @@ public final class ScopedValue<T> {
|
||||
* @return the result
|
||||
* @throws StructureViolationException if a structure violation is detected
|
||||
* @throws X if {@code op} completes with an exception
|
||||
* @since 23
|
||||
*/
|
||||
public <R, X extends Throwable> R call(CallableOp<? extends R, X> op) throws X {
|
||||
Objects.requireNonNull(op);
|
||||
@ -497,9 +493,8 @@ public final class ScopedValue<T> {
|
||||
*
|
||||
* @param <T> result type of the operation
|
||||
* @param <X> type of the exception thrown by the operation
|
||||
* @since 23
|
||||
* @since 25
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
|
||||
@FunctionalInterface
|
||||
public interface CallableOp<T, X extends Throwable> {
|
||||
/**
|
||||
@ -612,10 +607,11 @@ public final class ScopedValue<T> {
|
||||
* Returns the value of this scoped value if bound in the current thread, otherwise
|
||||
* returns {@code other}.
|
||||
*
|
||||
* @param other the value to return if not bound, can be {@code null}
|
||||
* @param other the value to return if not bound
|
||||
* @return the value of the scoped value if bound, otherwise {@code other}
|
||||
*/
|
||||
public T orElse(T other) {
|
||||
Objects.requireNonNull(other);
|
||||
Object obj = findBinding();
|
||||
if (obj != Snapshot.NIL) {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@ -300,7 +300,7 @@ public final class Subject implements java.io.Serializable {
|
||||
* @since 18
|
||||
*/
|
||||
public static Subject current() {
|
||||
return SCOPED_SUBJECT.orElse(null);
|
||||
return SCOPED_SUBJECT.isBound() ? SCOPED_SUBJECT.get() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -69,7 +69,6 @@ public @interface PreviewFeature {
|
||||
|
||||
//---
|
||||
IMPLICIT_CLASSES, //to be removed when boot JDK is 25
|
||||
@JEP(number=487, title="Scoped Values", status="Fourth Preview")
|
||||
SCOPED_VALUES,
|
||||
@JEP(number=505, title="Structured Concurrency", status="Fifth Preview")
|
||||
STRUCTURED_CONCURRENCY,
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Stress test ScopedValue with many bindings and rebindings
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @key randomness
|
||||
* @run junit ManyBindings
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Test ScopedValue API
|
||||
* @enablePreview
|
||||
* @run junit ScopedValueAPI
|
||||
*/
|
||||
|
||||
@ -175,18 +174,15 @@ class ScopedValueAPI {
|
||||
void testOrElse(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
assertNull(name.orElse(null));
|
||||
assertEquals("default", name.orElse("default"));
|
||||
|
||||
// where
|
||||
ScopedValue.where(name, "duke").run(() -> {
|
||||
assertEquals("duke", name.orElse(null));
|
||||
assertEquals("duke", name.orElse("default"));
|
||||
});
|
||||
|
||||
// callWhere
|
||||
ScopedValue.where(name, "duke").call(() -> {
|
||||
assertEquals("duke", name.orElse(null));
|
||||
assertEquals("duke", name.orElse("default"));
|
||||
return null;
|
||||
});
|
||||
@ -416,6 +412,7 @@ class ScopedValueAPI {
|
||||
assertThrows(NullPointerException.class, () -> ScopedValue.where(null, "duke").call(() -> ""));
|
||||
assertThrows(NullPointerException.class, () -> ScopedValue.where(name, "duke").call(null));
|
||||
|
||||
assertThrows(NullPointerException.class, () -> name.orElse(null));
|
||||
assertThrows(NullPointerException.class, () -> name.orElseThrow(null));
|
||||
|
||||
var carrier = ScopedValue.where(name, "duke");
|
||||
@ -423,6 +420,7 @@ class ScopedValueAPI {
|
||||
assertThrows(NullPointerException.class, () -> carrier.get((ScopedValue<?>)null));
|
||||
assertThrows(NullPointerException.class, () -> carrier.run(null));
|
||||
assertThrows(NullPointerException.class, () -> carrier.call(null));
|
||||
assertThrows(NullPointerException.class, () -> carrier.run(() -> name.orElse(null)));
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
||||
@ -26,7 +26,6 @@ import java.util.NoSuchElementException;
|
||||
/*
|
||||
* @test
|
||||
* @bug 8319120
|
||||
* @enablePreview
|
||||
* @run main/othervm -Xmx10m UnboundValueAfterOOME
|
||||
*/
|
||||
public class UnboundValueAfterOOME {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user