001: /*
002: * Mutex.java
003: *
004: * Copyright (C) 2004 Peter Graves
005: * $Id: Mutex.java,v 1.2 2004/09/09 14:59:29 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: /*
023: File: Mutex.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: */
034:
035: package org.armedbear.lisp;
036:
037: public final class Mutex extends LispObject {
038: private boolean inUse;
039:
040: public void acquire() throws InterruptedException {
041: if (Thread.interrupted())
042: throw new InterruptedException();
043: synchronized (this ) {
044: try {
045: while (inUse)
046: wait();
047: inUse = true;
048: } catch (InterruptedException e) {
049: notify();
050: throw e;
051: }
052: }
053: }
054:
055: public synchronized void release() {
056: inUse = false;
057: notify();
058: }
059:
060: public String writeToString() {
061: return unreadableString("MUTEX");
062: }
063:
064: // ### make-mutex => mutex
065: private static final Primitive MAKE_MUTEX = new Primitive(
066: "make-mutex", PACKAGE_EXT, true, "") {
067: public LispObject execute() throws ConditionThrowable {
068: return new Mutex();
069: }
070: };
071:
072: // ### get-mutex mutex => generalized-boolean
073: private static final Primitive GET_MUTEX = new Primitive(
074: "get-mutex", PACKAGE_EXT, true, "mutex") {
075: public LispObject execute(LispObject arg)
076: throws ConditionThrowable {
077: try {
078: ((Mutex) arg).acquire();
079: return T;
080: } catch (ClassCastException e) {
081: return signal(new TypeError("The value "
082: + arg.writeToString() + " is not a mutex."));
083: } catch (InterruptedException e) {
084: return signal(new LispError("The thread "
085: + LispThread.currentThread().writeToString()
086: + " was interrupted."));
087: }
088: }
089: };
090:
091: // ### release-mutex mutex
092: private static final Primitive RELEASE_MUTEX = new Primitive(
093: "release-mutex", PACKAGE_EXT, true, "mutex") {
094: public LispObject execute(LispObject arg)
095: throws ConditionThrowable {
096: try {
097: ((Mutex) arg).release();
098: return T;
099: } catch (ClassCastException e) {
100: return signal(new TypeError("The value "
101: + arg.writeToString() + " is not a mutex."));
102: }
103: }
104: };
105: }
|