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 }
|