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 */ 013 package 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 */ 030 public class SoftLatch { 031 032 private boolean open; 033 034 /** Create a new latch, with the given open/closed state. */ 035 public SoftLatch(boolean open) { 036 this.open = open; 037 } 038 039 /** 040 * Open the latch and let all of the thread(s) waiting on it through. 041 * But - if any of the threads is using waitAndClose(), then as soon 042 * as that thread awakes further threads will be blocked. 043 */ 044 public synchronized void open() { 045 open=true; 046 notifyAll(); 047 } 048 049 /** 050 * Close the latch, causing future calls to wait() or waitAndClose() 051 * to block. 052 */ 053 public synchronized void close() { 054 open=false; 055 } 056 057 /** 058 * Wait for the latch to become open. If it is already open, don't 059 * wait at all. 060 */ 061 public synchronized void await() { 062 while (!open) { 063 try { 064 wait(); 065 } catch (InterruptedException e) { 066 throw new Error(e); 067 } 068 } 069 } 070 071 /** 072 * Wait for the latch to become open, and then close it and return. 073 * If the latch is already open, don't wait at all, just close it 074 * immediately and return. 075 */ 076 public synchronized void waitAndClose() { 077 while (!open) { 078 try { 079 wait(); 080 } catch (InterruptedException e) { 081 throw new Error(e); 082 } 083 } 084 open=false; 085 } 086 }