001: //jTDS JDBC Driver for Microsoft SQL Server and Sybase
002: //Copyright (C) 2004 The jTDS Project
003: //
004: //This library is free software; you can redistribute it and/or
005: //modify it under the terms of the GNU Lesser General Public
006: //License as published by the Free Software Foundation; either
007: //version 2.1 of the License, or (at your option) any later version.
008: //
009: //This library is distributed in the hope that it will be useful,
010: //but WITHOUT ANY WARRANTY; without even the implied warranty of
011: //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: //Lesser General Public License for more details.
013: //
014: //You should have received a copy of the GNU Lesser General Public
015: //License along with this library; if not, write to the Free Software
016: //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: //
018: package net.sourceforge.jtds.jdbc;
019:
020: /**
021: * Simple semaphore class used to serialize access requests over the network
022: * connection.
023: * <p/>
024: * Based on the code originally written by Doug Lea. Once JDK 1.5 is the
025: * standard this class can be replaced by the
026: * <code>java.util.concurrent.Sempahore</code> class.
027: *
028: * @author Mike Hutchinson
029: * @version $Id: Semaphore.java,v 1.1 2004/12/20 15:51:17 alin_sinpalean Exp $
030: */
031: public class Semaphore {
032: /**
033: * Current number of available permits.
034: */
035: protected long permits;
036:
037: /**
038: * Create a Semaphore with the given initial number of permits. Using a
039: * seed of one makes the semaphore act as a mutual exclusion lock. Negative
040: * seeds are also allowed, in which case no acquires will proceed until the
041: * number of releases has pushed the number of permits past 0.
042: */
043: public Semaphore(long initialPermits) {
044: permits = initialPermits;
045: }
046:
047: /**
048: * Wait until a permit is available, and take one.
049: */
050: public void acquire() throws InterruptedException {
051: if (Thread.interrupted()) {
052: throw new InterruptedException();
053: }
054:
055: synchronized (this ) {
056: try {
057: while (permits <= 0) {
058: wait();
059: }
060: --permits;
061: } catch (InterruptedException ex) {
062: notify();
063: throw ex;
064: }
065: }
066: }
067:
068: /**
069: * Wait at most msecs millisconds for a permit.
070: */
071: public boolean attempt(long msecs) throws InterruptedException {
072: if (Thread.interrupted()) {
073: throw new InterruptedException();
074: }
075:
076: synchronized (this ) {
077: if (permits > 0) {
078: --permits;
079: return true;
080: } else if (msecs <= 0) {
081: return false;
082: } else {
083: try {
084: long startTime = System.currentTimeMillis();
085: long waitTime = msecs;
086:
087: while (true) {
088: wait(waitTime);
089:
090: if (permits > 0) {
091: --permits;
092: return true;
093: } else {
094: waitTime = msecs
095: - (System.currentTimeMillis() - startTime);
096: if (waitTime <= 0) {
097: return false;
098: }
099: }
100: }
101: } catch (InterruptedException ex) {
102: notify();
103: throw ex;
104: }
105: }
106: }
107: }
108:
109: /**
110: * Release a permit.
111: */
112: public synchronized void release() {
113: ++permits;
114: notify();
115: }
116:
117: /**
118: * Release N permits. <code>release(n)</code> is equivalent in effect to:
119: * <pre>
120: * for (int i = 0; i < n; ++i) release();
121: * </pre>
122: * <p/>
123: * But may be more efficient in some semaphore implementations.
124: *
125: * @exception IllegalArgumentException if n is negative
126: */
127: public synchronized void release(long n) {
128: if (n < 0) {
129: throw new IllegalArgumentException("Negative argument");
130: }
131:
132: permits += n;
133: for (long i = 0; i < n; ++i) {
134: notify();
135: }
136: }
137:
138: /**
139: * Return the current number of available permits. Returns an accurate, but
140: * possibly unstable value, that may change immediately after returning.
141: */
142: public synchronized long permits() {
143: return permits;
144: }
145: }
|