diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 90a642e5516c..a81efd4c9447 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -156,6 +156,8 @@ Improvements * GITHUB#12333: NumericLeafComparator#competitiveIterator makes better use of a "search after" value when paginating. (Chaitanya Gohel) +* GITHUB#12290: Make memory fence in ByteBufferGuard explicit using `VarHandle.fullFence()` + Optimizations --------------------- diff --git a/lucene/core/src/java/org/apache/lucene/store/ByteBufferGuard.java b/lucene/core/src/java/org/apache/lucene/store/ByteBufferGuard.java index 2d75597f9deb..a9e65ffa06c2 100644 --- a/lucene/core/src/java/org/apache/lucene/store/ByteBufferGuard.java +++ b/lucene/core/src/java/org/apache/lucene/store/ByteBufferGuard.java @@ -17,11 +17,11 @@ package org.apache.lucene.store; import java.io.IOException; +import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; -import java.util.concurrent.atomic.AtomicInteger; /** * A guard that is created for every {@link ByteBufferIndexInput} that tries on best effort to @@ -49,9 +49,6 @@ static interface BufferCleaner { /** Not volatile; see comments on visibility below! */ private boolean invalidated = false; - /** Used as a store-store barrier; see comments below! */ - private final AtomicInteger barrier = new AtomicInteger(); - /** * Creates an instance to be used for a single {@link ByteBufferIndexInput} which must be shared * by all of its clones. @@ -69,10 +66,9 @@ public void invalidateAndUnmap(ByteBuffer... bufs) throws IOException { // the "invalidated" field update visible to other threads. We specifically // don't make "invalidated" field volatile for performance reasons, hoping the // JVM won't optimize away reads of that field and hardware should ensure - // caches are in sync after this call. This isn't entirely "fool-proof" - // (see LUCENE-7409 discussion), but it has been shown to work in practice - // and we count on this behavior. - barrier.lazySet(0); + // caches are in sync after this call. + // For previous implementation (based on `AtomicInteger#lazySet(0)`) see LUCENE-7409. + VarHandle.fullFence(); // we give other threads a bit of time to finish reads on their ByteBuffer...: Thread.yield(); // finally unmap the ByteBuffers: