Skip to content

Commit

Permalink
Release delegate ref in Releasables#releaseOnce
Browse files Browse the repository at this point in the history
Like elastic#92452 and elastic#92507 but for `Releasables#releaseOnce`: there's no
need to keep hold of the wrapped releasable after closing it, and in
some cases this might hold on to excessive heap. With this commit we
drop the reference to the delegate when it's complete.
  • Loading branch information
DaveCTurner committed Dec 22, 2022
1 parent 3506d5e commit 9f176f7
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions libs/core/src/main/java/org/elasticsearch/core/Releasables.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

/** Utility methods to work with {@link Releasable}s. */
public enum Releasables {
Expand Down Expand Up @@ -98,13 +98,14 @@ public static Releasable wrap(final Releasable... releasables) {
}

/**
* Wraps a {@link Releasable} such that its {@link Releasable#close()} method can be called multiple times without double releasing.
* Wraps a {@link Releasable} such that its {@link Releasable#close()} method can be called multiple times without double-releasing.
*/
public static Releasable releaseOnce(final Releasable releasable) {
final AtomicBoolean released = new AtomicBoolean(false);
final var ref = new AtomicReference<>(releasable);
return () -> {
if (released.compareAndSet(false, true)) {
releasable.close();
final var acquired = ref.getAndSet(null);
if (acquired != null) {
acquired.close();
}
};
}
Expand Down

0 comments on commit 9f176f7

Please sign in to comment.