001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.scheduler; 014 015/** 016 * An implementation of a latch using monitors. 017 * This essentially gives you park/unpark functionality. It can also 018 * be used like the Win32-style AutoResetEvent or ManualResetEvent. 019 * <p> 020 * Park/unpark example: use open() to unpark and waitAndClose() to park. 021 * <p> 022 * AutoResetEvent example: use open() to set, close() to reset, and 023 * waitAndClose() to wait. 024 * <p> 025 * ManualResetEvent example: use open() to set, close() to reset, and 026 * wait() to wait. 027 * <p> 028 * Note: <b><i>never</i></b> synchronize on instances of this class. 029 */ 030public class SoftLatch { 031 032 private boolean open; 033 034 /** 035 * Creates a new latch, with the given open/closed state. 036 * @param open whether the latch is open at the beginning 037 */ 038 public SoftLatch(boolean open) { 039 this.open = open; 040 } 041 042 /** 043 * Open the latch and let all of the thread(s) waiting on it through. 044 * But - if any of the threads is using waitAndClose(), then as soon 045 * as that thread awakes further threads will be blocked. 046 */ 047 public synchronized void open() { 048 open = true; 049 notifyAll(); 050 } 051 052 /** 053 * Close the latch, causing future calls to wait() or waitAndClose() 054 * to block. 055 */ 056 public synchronized void close() { 057 open = false; 058 } 059 060 /** 061 * Wait for the latch to become open. If it is already open, don't 062 * wait at all. 063 */ 064 public synchronized void await() { 065 while (!open) { 066 try { 067 wait(); 068 } catch (InterruptedException e) { 069 throw new Error(e); 070 } 071 } 072 } 073 074 /** 075 * Wait for the latch to become open, and then close it and return. 076 * If the latch is already open, don't wait at all, just close it 077 * immediately and return. 078 */ 079 public synchronized void waitAndClose() { 080 while (!open) { 081 try { 082 wait(); 083 } catch (InterruptedException e) { 084 throw new Error(e); 085 } 086 } 087 open = false; 088 } 089}