1package dev.rafex.ether.di;
29import java.util.ArrayDeque;
30import java.util.Deque;
31import java.util.concurrent.atomic.AtomicBoolean;
54public final class Closer implements AutoCloseable {
56 private final Deque<AutoCloseable> resources =
new ArrayDeque<>();
57 private final AtomicBoolean closed =
new AtomicBoolean(
false);
66 public <T extends AutoCloseable> T register(
final T resource) {
67 if (resource ==
null) {
68 throw new NullPointerException(
"resource");
70 synchronized (resources) {
71 resources.push(resource);
86 if (!closed.compareAndSet(
false,
true)) {
89 Throwable first =
null;
91 final AutoCloseable resource;
92 synchronized (resources) {
93 resource = resources.isEmpty() ? null : resources.pop();
95 if (resource ==
null) {
100 }
catch (
final Throwable t) {
104 first.addSuppressed(t);
109 if (first instanceof RuntimeException re) {
112 throw new RuntimeException(
"Error closing resources", first);
Composite AutoCloseable that closes registered resources in LIFO order.
boolean isClosed()
Returns true if close() has already been called.
void close()
Closes all registered resources in LIFO order.