Source code for /engineering/autohit-2003/src/autohit/vm/VMObject.javaOriginal file VMObject.java
   1 /**
   2  * AUTOHIT 2003
   3  * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
   4  * 
   5  * This program is free software; you can redistribute it and/or modify 
   6  * it under the terms of the GNU General Public License as published by 
   7  * the Free Software Foundation; either version 2 of the License, or (at
   8  * your option) any later version.
   9  * This program is distributed in the hope that it will be useful, but
  10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12  * more details.
  13  * 
  14  * You should have received a copy of the GNU General Public License along
  15  * with this program; if not, write to the Free Software Foundation, Inc.,
  16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17  *
  18  * Additional license information can be found in the documentation.
  19  * @author Erich P Gatejen
  20  */
  21 package autohit.vm;
  22 import autohit.common.Constants;
  23 import autohit.common.ThreadContext;
  24 
  25 /**
  26  * This is a lock-able, set-able object.  Field item holds the actual
  27  * data.
  28  * <p>
  29  * @author Erich P. Gatejen
  30  * @version 1.0
  31  * <i>Version History</i>
  32  * <code>EPG - Initial - 8may03</code> 
  33  * 
  34  */
  35 public class VMObject {
  36 
  37 	private Object item;
  38 	private int owner;
  39 	private int lockcount;
  40 
  41 	/**
  42 	 * Default Constructor.
  43 	 */
  44 	public VMObject() {
  45 		owner = 0;
  46 		item = null;
  47 	}
  48 
  49 	/**
  50 	 * Creator Constructor.
  51 	 * @param o the object
  52 	 */
  53 	public VMObject(Object o) {
  54 		owner = Constants.NO_OWNER;
  55 		item = null;
  56 		item = o;
  57 	}
  58 
  59 	/**
  60 	 * The calling thread will try to lock it.  If successful, it will spinlock 
  61 	 * it
  62 	 * @throws VMException if it is already locked.
  63 	 */
  64 	public synchronized void lock() throws VMException {
  65 
  66 		int me = ThreadContext.get();
  67 		if ((owner != Constants.NO_OWNER) && (owner != me)) {
  68 			throw new VMException(
  69 				"Object locked by id#" + owner,
  70 				VMException.CODE_VM_OBJECT_LOCKED_FAULT);
  71 		}
  72 		owner = me;
  73 		lockcount++;
  74 	}
  75 
  76 	/**
  77 	 *  Test if I can access it
  78 	 * @return true if I can
  79 	 */
  80 	public synchronized boolean test() {
  81 
  82 		if ((owner == Constants.NO_OWNER) || (owner == ThreadContext.get())) {
  83 			return true;
  84 		}
  85 		return false;
  86 	}
  87 
  88 	/**
  89 	 *  Knock the spinlock down one.  If it hits zero, the lock is
  90 	 *  removed.
  91 	 * 	@throws VMException if it locked by something else.
  92 	 */
  93 	public void unlock() throws VMException {
  94 
  95 		if ((owner == Constants.NO_OWNER) || (owner == ThreadContext.get())) {
  96 			throw new VMException(
  97 				"Object locked by id#" + owner,
  98 				VMException.CODE_VM_OBJECT_LOCKED_FAULT);
  99 		}
 100 
 101 		lockcount--;
 102 		if (lockcount <= 0) {
 103 			lockcount = 0;
 104 			owner = Constants.NO_OWNER;
 105 			item.notifyAll();
 106 		}
 107 	}
 108 
 109 	/**
 110 	 *  Cancel all locks
 111 	 * 	@throws VMException if it locked by something else.
 112 	 */
 113 	public synchronized void free() throws VMException {
 114 
 115 		if ((owner == Constants.NO_OWNER) || (owner == ThreadContext.get())) {
 116 			throw new VMException(
 117 				"Object locked by id#" + owner,
 118 				VMException.CODE_VM_OBJECT_LOCKED_FAULT);
 119 		}
 120 		owner = Constants.NO_OWNER;
 121 		lockcount = 0;
 122 	}
 123 
 124 	/**
 125 	 *  Set the object
 126 	 * 	@throws VMException if it locked by something else.
 127 	 */
 128 	public synchronized void set(Object o) throws VMException {
 129 
 130 		if ((owner == Constants.NO_OWNER) || (owner == ThreadContext.get())) {
 131 			item = o;
 132 
 133 		} else {
 134 			throw new VMException(
 135 				"Object locked by id#" + owner,
 136 				VMException.CODE_VM_OBJECT_LOCKED_FAULT);
 137 		}
 138 	}
 139 
 140 	/**
 141 	 *  Get the object
 142 	 * 	@throws VMException if it locked by something else.
 143 	 * @return the object
 144 	 */
 145 	public synchronized Object get() throws VMException {
 146 
 147 		if ((owner == Constants.NO_OWNER) || (owner == ThreadContext.get())) {
 148 			return item;
 149 
 150 		} else {
 151 			throw new VMException(
 152 				"Object locked by id#" + owner,
 153 				VMException.CODE_VM_OBJECT_LOCKED_FAULT);
 154 		}
 155 	}
 156 
 157 	/**
 158 	 *  Get the object.  Wait for it to be free if locked.
 159 	 * This is pretty dangerous source of deadlock.  Be careful!
 160 	 * 	@throws VMException if it locked by something else.
 161 	 * 	@return the object
 162 	 */
 163 	public Object waitingRead() {
 164 
 165 		Object thang = null;
 166 
 167 		while (thang == null) {
 168 
 169 			// synchronize to keep the stooges from barging the door
 170 			// the threads waiting for the item will all get unleashed at once.
 171 			synchronized (this) {
 172 				if ((owner == Constants.NO_OWNER)
 173 					|| (owner == ThreadContext.get())) {
 174 					// If it owns it, there is no wait.
 175 					thang = item;
 176 				}
 177 			}
 178 			try {
 179 				item.wait();
 180 			} catch (Exception e) {
 181 				// Don't care
 182 			}
 183 
 184 		}
 185 		return thang;
 186 	}
 187 
 188 	/**
 189 	 *  Get the object.  Wait for it to be free if locked.
 190 	 * This is pretty dangerous source of deadlock.  Be careful!
 191 	 * 	@throws VMException if it locked by something else.
 192 	 * 	@return the object
 193 	 */
 194 	public void waitingLock() {
 195 
 196 		while (true) {
 197 
 198 			// synchronize to keep the stooges from barging the door
 199 			// the threads waiting for the item will all get unleashed at once.
 200 			synchronized (this) {
 201 				if ((owner == Constants.NO_OWNER)
 202 					|| (owner == ThreadContext.get())) {
 203 					// If it owns it, there is no wait.
 204 					try {
 205 						this.lock();
 206 						return;
 207 					} catch (Exception e) {
 208 						// someone beat us to it!  Keep waiting.
 209 					}
 210 				}
 211 			}
 212 			try {
 213 				item.wait();
 214 			} catch (Exception e) {
 215 				// Don't care
 216 			}
 217 
 218 		}
 219 	}
 220 
 221 }