001    // This file is part of the program FRYSK.
002    //
003    // Copyright 2007, Red Hat Inc.
004    //
005    // FRYSK is free software; you can redistribute it and/or modify it
006    // under the terms of the GNU General Public License as published by
007    // the Free Software Foundation; version 2 of the License.
008    //
009    // FRYSK is distributed in the hope that it will be useful, but
010    // WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012    // General Public License for more details.
013    // 
014    // You should have received a copy of the GNU General Public License
015    // along with FRYSK; if not, write to the Free Software Foundation,
016    // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017    // 
018    // In addition, as a special exception, Red Hat, Inc. gives You the
019    // additional right to link the code of FRYSK with code not covered
020    // under the GNU General Public License ("Non-GPL Code") and to
021    // distribute linked combinations including the two, subject to the
022    // limitations in this paragraph. Non-GPL Code permitted under this
023    // exception must only link to the code of FRYSK through those well
024    // defined interfaces identified in the file named EXCEPTION found in
025    // the source code files (the "Approved Interfaces"). The files of
026    // Non-GPL Code may instantiate templates or use macros or inline
027    // functions from the Approved Interfaces without causing the
028    // resulting work to be covered by the GNU General Public
029    // License. Only Red Hat, Inc. may make changes or additions to the
030    // list of Approved Interfaces. You must obey the GNU General Public
031    // License in all respects for all of the FRYSK code and other code
032    // used in conjunction with FRYSK except the Non-GPL Code covered by
033    // this exception. If you modify this file, you may extend this
034    // exception to your version of the file, but you are not obligated to
035    // do so. If you do not wish to provide this exception without
036    // modification, you must delete this exception statement from your
037    // version and license this file solely under the GPL without
038    // exception.
039    
040    package frysk.util;
041    
042    /**
043     * Implementation of CountDownLatch from java.util.concurrent in Java
044     * 1.5
045     */
046    public class CountDownLatch {
047        private int count;
048    
049        public CountDownLatch(int count)
050        throws IllegalArgumentException {
051            if (count < 0)
052                throw new IllegalArgumentException("count is less than 0");
053            this.count = count;
054        }
055    
056        public synchronized void await()
057            throws InterruptedException {
058            while (count != 0) {
059                try {
060                    wait();
061                }
062                catch (InterruptedException e) {
063                    throw e;
064                }
065            }
066        }
067    
068        public synchronized boolean await(long timeout)
069            throws InterruptedException {
070            if (count == 0)
071                return true;
072            long now = System.currentTimeMillis();
073            while (count != 0) {
074                long later = now + timeout;
075                try {
076                    wait(timeout);
077                }
078                catch (InterruptedException e) {
079                    throw e;
080                }
081                now = System.currentTimeMillis();
082                if (now >= later)
083                    break;
084                timeout = later - now;
085            }
086            // Either the count is 0 or we timed out
087            return count == 0;
088        }
089    
090        public synchronized void countDown() {
091            if (count == 0)
092                return;
093            --count;
094            if (count == 0)
095                notifyAll();
096        }
097    
098        public synchronized long getCount() {
099            return count;
100        }
101    
102        public String toString() {
103            return super.toString() + " [Count=" + getCount() + "]";
104        }
105    }