package org.infinispan.util; /** * A latch that can be open and close. It allows the notification when the some thread is blocking in it. * * @author Pedro Ruivo * @since 6.0 */ public class NotifierLatch { private boolean enabled = false; private boolean blocked = false; private int disableOnUnblock = 0; public final synchronized void startBlocking() { this.enabled = true; } public final synchronized void stopBlocking() { this.enabled = false; this.disableOnUnblock = 0; notifyAll(); } public final synchronized void blockIfNeeded() { blocked = true; notifyAll(); try { while (enabled) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } } finally { blocked = false; if (disableOnUnblock > 0 && --disableOnUnblock == 0) { enabled = true; } } } public final synchronized void waitToBlock() throws InterruptedException { while (!blocked) { wait(); } } public synchronized void unblockOnce() { enabled = false; disableOnUnblock++; notifyAll(); } public void waitToBlockAndUnblockOnce() throws InterruptedException { waitToBlock(); unblockOnce(); } @Override public String toString() { final StringBuilder sb = new StringBuilder("NotifierLatch{"); sb.append("enabled=").append(enabled); sb.append(", blocked=").append(blocked); sb.append(", disableOnUnblock=").append(disableOnUnblock); sb.append('}'); return sb.toString(); } }