@Test public void testClose_multipleTimesDoNothing() throws IOException { state.close(); assertEquals(1, onClose.runCount); state.close(); state.close(); assertEquals(1, onClose.runCount); }
@Override public void close() throws IOException { if (open.compareAndSet(true, false)) { onClose.run(); Throwable thrown = null; do { for (Closeable resource : resources) { try { resource.close(); } catch (Throwable e) { if (thrown == null) { thrown = e; } else { thrown.addSuppressed(e); } } finally { resources.remove(resource); } } } while (registering.get() > 0 || !resources.isEmpty()); Throwables.propagateIfPossible(thrown, IOException.class); } }
FileSystemState implements Closeable { @Override public void close() throws IOException { if (open.compareAndSet(true, false)) { onClose.run(); Throwable thrown = null; do { for (Closeable resource : resources) { try { resource.close(); } catch (Throwable e) { if (thrown == null) { thrown = e; } else { thrown.addSuppressed(e); } } finally { resources.remove(resource); } } } while (registering.get() > 0 || !resources.isEmpty()); Throwables.propagateIfPossible(thrown, IOException.class); } } }
FileSystemState implements Closeable { @Override public void close() throws IOException { if (open.compareAndSet(true, false)) { onClose.run(); Throwable thrown = null; do { for (Closeable resource : resources) { try { resource.close(); } catch (Throwable e) { if (thrown == null) { thrown = e; } else { thrown.addSuppressed(e); } } finally { resources.remove(resource); } } } while (registering.get() > 0 || !resources.isEmpty()); Throwables.propagateIfPossible(thrown, IOException.class); } } FileSystemState(Runnable onClose); }
FileSystemState implements Closeable { @Override public void close() throws IOException { if (open.compareAndSet(true, false)) { onClose.run(); Throwable thrown = null; do { for (Closeable resource : resources) { try { resource.close(); } catch (Throwable e) { if (thrown == null) { thrown = e; } else { thrown.addSuppressed(e); } } finally { resources.remove(resource); } } } while (registering.get() > 0 || !resources.isEmpty()); Throwables.propagateIfPossible(thrown, IOException.class); } } FileSystemState(Runnable onClose); boolean isOpen(); void checkOpen(); C register(C resource); void unregister(Closeable resource); @Override void close(); }
FileSystemState implements Closeable { @Override public void close() throws IOException { if (open.compareAndSet(true, false)) { onClose.run(); Throwable thrown = null; do { for (Closeable resource : resources) { try { resource.close(); } catch (Throwable e) { if (thrown == null) { thrown = e; } else { thrown.addSuppressed(e); } } finally { resources.remove(resource); } } } while (registering.get() > 0 || !resources.isEmpty()); Throwables.propagateIfPossible(thrown, IOException.class); } } FileSystemState(Runnable onClose); boolean isOpen(); void checkOpen(); C register(C resource); void unregister(Closeable resource); @Override void close();  }