Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,9 @@ public final <T> T getExtension(SchemaExtensionKey<T> key) {
if (key.id >= ext.length) {
return null;
}
// Plain array read (benign race). Safe because extension objects are immutable
// (records with final fields), and Java's final field semantics (JLS 17.5)
// guarantee visibility once the reference is seen. Worst case: redundant computation.
// Plain array read (benign race). Safe because extension objects are safely publishable,
// and Java's final field semantics (JLS 17.5) guarantee visibility once the reference is
// seen. Worst case: redundant computation or independent cache holders.
var value = ext[key.id];
if (value == NOT_COMPUTED) {
value = computeExtension(key, ext);
Expand All @@ -494,8 +494,8 @@ private Object computeExtension(SchemaExtensionKey<?> key, Object[] ext) {
var value = provider.provide(this);
result = value != null ? value : NULL_SENTINEL;
}
// Plain array write (benign race). The stored object is immutable, so any thread
// that later reads this element and sees the object will see all its final fields.
// Plain array write (benign race). Any thread that later reads this element and sees
// the safely publishable object will see all its final fields.
ext[key.id] = result;
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public interface SchemaExtensionProvider<T> {
* returns.</li>
* </ul>
*
* <p>An extension may use thread-safe mutable state as a performance cache when the cache is held in
* final fields, all cache access uses appropriate synchronization or atomic operations, and cache
* contents do not affect behavior. Because concurrent extension computation can produce independent
* instances, losing the contents of one such cache must only result in redundant computation.
*
* <p><b>Idempotency:</b> Under concurrent access, multiple threads may invoke this method
* simultaneously for the same schema and key (benign race). All invocations must produce
* equivalent results.
Expand Down
Loading
Loading