/** this class is fully thread-safe */ class Flag { private boolean up; private Trigger listeners = new Trigger(); /** returns true if flag was down before */ public synchronized boolean raise() { boolean result = doRaise(); if (result) { listeners.trigger(); listeners = null; } return result; } private synchronized boolean doRaise() { if (!up) { up = true; notifyAll(); return true; } else return false; } public synchronized void waitUntilUp() { if (!up) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public void onRaise(Runnable listener) { if (!addListener(listener)) listener.run(); } private synchronized boolean addListener(Runnable listener) { if (!up) { listeners.addListener(listener); return true; } else return false; } public synchronized boolean isUp() { return up; } public String toString() { return isUp() ? "up" : "down"; } // currently does a semi-active wait with latency = 50 ms public void waitForThisOr(Flag otherFlag) { while (!isUp() && !otherFlag.isUp()) MultiCoreUtil.sleep(50); } }