001: /* Modified by cougaar
002: * <copyright>
003: * Copyright 2006 BBNT Solutions, LLC
004: * under sponsorship of the Defense Advanced Research Projects Agency (DARPA).
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the Cougaar Open Source License as published by
008: * DARPA on the Cougaar Open Source Website (www.cougaar.org).
009: *
010: * THE COUGAAR SOFTWARE AND ANY DERIVATIVE SUPPLIED BY LICENSOR IS
011: * PROVIDED 'AS IS' WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS OR
012: * IMPLIED, INCLUDING (BUT NOT LIMITED TO) ALL IMPLIED WARRANTIES OF
013: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND WITHOUT
014: * ANY WARRANTIES AS TO NON-INFRINGEMENT. IN NO EVENT SHALL COPYRIGHT
015: * HOLDER BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL
016: * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE OF DATA OR PROFITS,
017: * TORTIOUS CONDUCT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
018: * PERFORMANCE OF THE COUGAAR SOFTWARE.
019: * </copyright>
020: */
021:
022: /*
023: File: Semaphore.java
024:
025: Originally written by Doug Lea and released into the public domain.
026: This may be used for any purposes whatsoever without acknowledgment.
027: Thanks for the assistance and support of Sun Microsystems Labs,
028: and everyone contributing, testing, and using this code.
029:
030: History:
031: Date Who What
032: 11Jun1998 dl Create public version
033: 5Aug1998 dl replaced int counters with longs
034: 24Aug1999 dl release(n): screen arguments
035: */
036:
037: package org.cougaar.community.util;
038:
039: /**
040: * Copied from <code>EDU.oswego.cs.dl.util.concurrent.Semaphore</code> to
041: * avoid the extra "sys/concurrent.jar" dependency.
042: */
043: public class Semaphore {
044: /** current number of available permits **/
045: protected long permits_;
046:
047: /**
048: * Create a Semaphore with the given initial number of permits.
049: * Using a seed of one makes the semaphore act as a mutual exclusion lock.
050: * Negative seeds are also allowed, in which case no acquires will proceed
051: * until the number of releases has pushed the number of permits past 0.
052: **/
053: public Semaphore(long initialPermits) {
054: permits_ = initialPermits;
055: }
056:
057: /** Wait until a permit is available, and take one **/
058: public void acquire() throws InterruptedException {
059: if (Thread.interrupted())
060: throw new InterruptedException();
061: synchronized (this ) {
062: try {
063: while (permits_ <= 0)
064: wait();
065: --permits_;
066: } catch (InterruptedException ex) {
067: notify();
068: throw ex;
069: }
070: }
071: }
072:
073: /** Wait at most msecs millisconds for a permit. **/
074: public boolean attempt(long msecs) throws InterruptedException {
075: if (Thread.interrupted())
076: throw new InterruptedException();
077:
078: synchronized (this ) {
079: if (permits_ > 0) {
080: --permits_;
081: return true;
082: } else if (msecs <= 0)
083: return false;
084: else {
085: try {
086: long startTime = System.currentTimeMillis();
087: long waitTime = msecs;
088:
089: for (;;) {
090: wait(waitTime);
091: if (permits_ > 0) {
092: --permits_;
093: return true;
094: } else {
095: waitTime = msecs
096: - (System.currentTimeMillis() - startTime);
097: if (waitTime <= 0)
098: return false;
099: }
100: }
101: } catch (InterruptedException ex) {
102: notify();
103: throw ex;
104: }
105: }
106: }
107: }
108:
109: /** Release a permit **/
110: public synchronized void release() {
111: ++permits_;
112: notify();
113: }
114:
115: /**
116: * Release N permits. <code>release(n)</code> is
117: * equivalent in effect to:
118: * <pre>
119: * for (int i = 0; i < n; ++i) release();
120: * </pre>
121: * <p>
122: * But may be more efficient in some semaphore implementations.
123: * @exception IllegalArgumentException if n is negative.
124: **/
125: public synchronized void release(long n) {
126: if (n < 0)
127: throw new IllegalArgumentException("Negative argument");
128:
129: permits_ += n;
130: for (long i = 0; i < n; ++i)
131: notify();
132: }
133:
134: /**
135: * Return the current number of available permits.
136: * Returns an accurate, but possibly unstable value,
137: * that may change immediately after returning.
138: **/
139: public synchronized long permits() {
140: return permits_;
141: }
142: }
|