/* booleanSempahore.java Handy, simple synchronized flag class Created: 29 March 2001 Module By: Jonathan Abbey ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2013 The University of Texas at Austin Ganymede is a registered trademark of The University of Texas at Austin Contact information Web site: http://www.arlut.utexas.edu/gash2 Author Email: ganymede_author@arlut.utexas.edu Email mailing list: ganymede@arlut.utexas.edu US Mail: Computer Science Division Applied Research Laboratories The University of Texas at Austin PO Box 8029, Austin TX 78713-8029 Telephone: (512) 835-3200 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package arlut.csd.Util; /*------------------------------------------------------------------------------ class booleanSempahore ------------------------------------------------------------------------------*/ /** * <p>Simple, synchronized boolean flag class.</p> * * <p>This class is useful for providing a reliable boolean flag that * can be examined by separate threads without worry over funky memory * model behavior on multiprocessor systems, etc.</p> * * <p>This class is serializable only because the Ganymede {@link * arlut.csd.ganymede.common.scheduleHandle} class includes a * booleanSempahore for server-side use, and {@link * arlut.csd.ganymede.common.scheduleHandle} objects are themselves * serializable. Obviously, we don't really care too much about fancy * multithreaded semantics when we are being serialized.</p> */ public class booleanSemaphore implements java.io.Serializable { static final long serialVersionUID = -3446577789138582378L; private boolean state; /* -- */ public booleanSemaphore(boolean initialState) { this.state = initialState; } public synchronized boolean isSet() { return state; } /** * <p>Simple bidirectional test and set.</p> * * @return The value that the booleanSemaphore had * before set() was called. */ public synchronized boolean set(boolean b) { boolean old; /* -- */ old = state; state = b; this.notifyAll(); return old; } /** * <p>Safe, simple method to wait until this boolean semaphore has * been cleared. If the semaphore is already cleared at the time * this method is called, this method will return immediately.</p> * * <p>Note that this method will not time out.</p> */ public synchronized void waitForCleared() { while (state) { try { wait(); } catch (InterruptedException ex) { } } } /** * <p>Safe, simple method to wait until this boolean semaphore has * been cleared, or until at least millis milliseconds have passed. * If the semaphore is already cleared at the time this method is * called, this method will return immediately.</p> * * @return the state of the semaphore at the time the method * returns.. this will be false if the semaphore was cleared, or * true if the wait timed out before the semaphore was cleared */ public synchronized boolean waitForCleared(long millis) { if (!state) { return state; } long waitTime = millis; long startTime = System.currentTimeMillis(); long timeSoFar = 0; /* -- */ while (state) { // we already know from above that we have to wait, so // we'll start the loop waiting try { wait(waitTime); } catch (InterruptedException ex) { } timeSoFar = System.currentTimeMillis() - startTime; if (timeSoFar > millis) // timed out { return state; } else { waitTime = millis - timeSoFar; } } return state; } /** * <p>Safe, simple method to wait until this boolean semaphore has * been set. If the semaphore is already set at the time this method * is called, this method will return immediately.</p> * * <p>Note that this method will not time out.</p> */ public synchronized void waitForSet() { while (!state) { try { wait(); } catch (InterruptedException ex) { } } } /** * <p>Safe, simple method to wait until this boolean semaphore has * been cleared, or until at least millis milliseconds have * passed. If the semaphore is already set at the time this method * is called, this method will return immediately.</p> * * @return the state of the semaphore at the time the method * returns.. this will be true if the semaphore was set, or false if * the wait timed out before the semaphore was set */ public synchronized boolean waitForSet(long millis) { if (state) { return state; } long waitTime = millis; long startTime = System.currentTimeMillis(); long timeSoFar = 0; /* -- */ while (!state) { // we already know from above that we have to wait, so // we'll start the loop waiting try { wait(waitTime); } catch (InterruptedException ex) { } timeSoFar = System.currentTimeMillis() - startTime; if (timeSoFar > millis) // timed out { return state; } else { waitTime = millis - timeSoFar; } } return state; } }