/** * Expert: decreases the refCount of this IndexReader instance. If the refCount drops to 0, then * this reader is closed. If an exception is hit, the refCount is unchanged. * * @throws IOException in case an IOException occurs in doClose() * @see #incRef */ public final void decRef() throws IOException { // only check refcount here (don't call ensureOpen()), so we can // still close the reader if it was made invalid by a child: if (refCount.get() <= 0) { throw new AlreadyClosedException("this IndexReader is closed"); } final int rc = refCount.decrementAndGet(); if (rc == 0) { closed = true; Throwable throwable = null; try { doClose(); } catch (Throwable th) { throwable = th; } finally { try { reportCloseToParentReaders(); } finally { notifyReaderClosedListeners(throwable); } } } else if (rc < 0) { throw new IllegalStateException( "too many decRef calls: refCount is " + rc + " after decrement"); } }
private void reportCloseToParentReaders() { synchronized (parentReaders) { for (IndexReader parent : parentReaders) { parent.closedByChild = true; // cross memory barrier by a fake write: parent.refCount.addAndGet(0); // recurse: parent.reportCloseToParentReaders(); } } }