KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > msg > LockRequestMessage


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.msg;
6
7 import com.tc.bytes.TCByteBuffer;
8 import com.tc.io.TCByteBufferOutput;
9 import com.tc.io.TCSerializable;
10 import com.tc.net.protocol.tcm.MessageChannel;
11 import com.tc.net.protocol.tcm.MessageMonitor;
12 import com.tc.net.protocol.tcm.TCMessageHeader;
13 import com.tc.net.protocol.tcm.TCMessageType;
14 import com.tc.object.lockmanager.api.LockContext;
15 import com.tc.object.lockmanager.api.LockID;
16 import com.tc.object.lockmanager.api.LockLevel;
17 import com.tc.object.lockmanager.api.ThreadID;
18 import com.tc.object.lockmanager.api.WaitContext;
19 import com.tc.object.session.SessionID;
20 import com.tc.object.tx.WaitInvocation;
21 import com.tc.object.tx.WaitInvocationFactory;
22
23 import java.io.IOException JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Set JavaDoc;
28
29 /**
30  * Message for obtaining/releasing locks, and for modifying them (ie. wait/notify)
31  *
32  * @author steve
33  */

34 public class LockRequestMessage extends DSOMessageBase {
35
36   private static final WaitInvocationFactory waitInvocationFactory = new WaitInvocationFactory();
37
38   private final static byte LOCK_ID = 1;
39   private final static byte LOCK_LEVEL = 2;
40   private final static byte THREAD_ID = 3;
41   private final static byte REQUEST_TYPE = 4;
42   private final static byte WITH_WAIT = 5;
43   private final static byte WAIT_MILLIS = 6;
44   private final static byte WAIT_NANOS = 7;
45   private final static byte NOTIFY_ALL = 8;
46   private static final byte WAIT_ARG_COUNT = 9;
47   private static final byte WAIT_CONTEXT = 10;
48   private static final byte LOCK_CONTEXT = 11;
49   private static final byte PENDING_LOCK_CONTEXT = 12;
50
51   // request types
52
private final static byte UNITIALIZED_REQUEST_TYPE = -1;
53   private final static byte OBTAIN_LOCK_REQUEST_TYPE = 1;
54   private final static byte RELEASE_LOCK_REQUEST_TYPE = 2;
55   private final static byte RECALL_COMMIT_LOCK_REQUEST_TYPE = 3;
56   private final static byte QUERY_LOCK_REQUEST_TYPE = 4;
57   private final static byte TRY_OBTAIN_LOCK_REQUEST_TYPE = 5;
58   private final static byte INTERRUPT_WAIT_REQUEST_TYPE = 6;
59
60   public final static int UNITIALIZED_WAIT_TIME = -1;
61
62   private final Set JavaDoc lockContexts = new HashSet JavaDoc();
63   private final Set JavaDoc waitContexts = new HashSet JavaDoc();
64   private final Set JavaDoc pendingLockContexts = new HashSet JavaDoc();
65
66   private LockID lockID = LockID.NULL_ID;
67   private int lockLevel = LockLevel.NIL_LOCK_LEVEL;
68   private ThreadID threadID = ThreadID.NULL_ID;
69   private byte requestType = UNITIALIZED_REQUEST_TYPE;
70   private boolean withWait;
71   private long waitMillis = UNITIALIZED_WAIT_TIME;
72   private int waitNanos = UNITIALIZED_WAIT_TIME;
73   private boolean notifyAll;
74   private int waitArgCount = -1;
75
76   public LockRequestMessage(MessageMonitor monitor, TCByteBufferOutput out, MessageChannel channel, TCMessageType type) {
77     super(monitor, out, channel, type);
78   }
79
80   public LockRequestMessage(SessionID sessionID, MessageMonitor monitor, MessageChannel channel,
81                             TCMessageHeader header, TCByteBuffer[] data) {
82     super(sessionID, monitor, channel, header, data);
83   }
84
85   protected void dehydrateValues() {
86     putNVPair(LOCK_ID, lockID.asString());
87     putNVPair(LOCK_LEVEL, lockLevel);
88     putNVPair(THREAD_ID, threadID.toLong());
89
90     putNVPair(REQUEST_TYPE, requestType);
91
92     putNVPair(WITH_WAIT, withWait);
93
94     if (withWait) {
95       putNVPair(WAIT_ARG_COUNT, this.waitArgCount);
96       putNVPair(WAIT_MILLIS, waitMillis);
97       putNVPair(WAIT_NANOS, waitNanos);
98     }
99
100     putNVPair(NOTIFY_ALL, notifyAll);
101
102     for (Iterator JavaDoc i = lockContexts.iterator(); i.hasNext();) {
103       putNVPair(LOCK_CONTEXT, (TCSerializable) i.next());
104     }
105
106     for (Iterator JavaDoc i = waitContexts.iterator(); i.hasNext();) {
107       putNVPair(WAIT_CONTEXT, (TCSerializable) i.next());
108     }
109
110     for (Iterator JavaDoc i = pendingLockContexts.iterator(); i.hasNext();) {
111       putNVPair(PENDING_LOCK_CONTEXT, (TCSerializable) i.next());
112     }
113
114   }
115
116   private static boolean isValidRequestType(byte type) {
117     if ((type == RELEASE_LOCK_REQUEST_TYPE) || (type == OBTAIN_LOCK_REQUEST_TYPE)
118         || (type == RECALL_COMMIT_LOCK_REQUEST_TYPE) || (type == QUERY_LOCK_REQUEST_TYPE)
119         || (type == TRY_OBTAIN_LOCK_REQUEST_TYPE) || (type == INTERRUPT_WAIT_REQUEST_TYPE)) { return true; }
120
121     return false;
122   }
123
124   private static String JavaDoc getRequestTypeDescription(byte type) {
125     switch (type) {
126       case RELEASE_LOCK_REQUEST_TYPE:
127         return "Lock Release";
128       case OBTAIN_LOCK_REQUEST_TYPE:
129         return "Obtain Lock";
130       case RECALL_COMMIT_LOCK_REQUEST_TYPE:
131         return "Recall Lock Commit";
132       case QUERY_LOCK_REQUEST_TYPE:
133         return "Query Lock";
134       case TRY_OBTAIN_LOCK_REQUEST_TYPE:
135         return "Try Obtain Lock";
136       case INTERRUPT_WAIT_REQUEST_TYPE:
137         return "Interrupt Wait";
138       default:
139         return "UNKNOWN (" + type + ")";
140     }
141   }
142
143   protected String JavaDoc describePayload() {
144     StringBuffer JavaDoc rv = new StringBuffer JavaDoc();
145
146     rv.append("Request Type: ").append(getRequestTypeDescription(this.requestType)).append('\n');
147     rv.append(lockID).append(' ').append(threadID).append(' ').append("Lock Type: ").append(
148                                                                                             LockLevel
149                                                                                                 .toString(lockLevel))
150         .append('\n');
151
152     if (isWaitRelease()) {
153       rv.append("Wait millis: ").append(waitMillis).append(", nanos: ").append(waitNanos).append('\n');
154     }
155     if (waitContexts.size() > 0) {
156       rv.append("Wait contexts size = ").append(waitContexts.size()).append('\n');
157     }
158     if (lockContexts.size() > 0) {
159       rv.append("Lock contexts size = ").append(lockContexts.size()).append('\n');
160     }
161     if (pendingLockContexts.size() > 0) {
162       rv.append("Pending Lock contexts size = ").append(pendingLockContexts.size()).append('\n');
163     }
164
165     return rv.toString();
166   }
167
168   protected boolean hydrateValue(byte name) throws IOException JavaDoc {
169     switch (name) {
170       case LOCK_ID:
171         // TODO: Make this use a lockID factory so that we can avoid dups
172
lockID = new LockID(getStringValue());
173         return true;
174       case LOCK_LEVEL:
175         lockLevel = getIntValue();
176         return true;
177       case THREAD_ID:
178         threadID = new ThreadID(getLongValue());
179         return true;
180       case WITH_WAIT:
181         withWait = getBooleanValue();
182         return true;
183       case REQUEST_TYPE:
184         final byte req = getByteValue();
185         if (!isValidRequestType(req)) { return false; }
186         requestType = req;
187         return true;
188       case WAIT_MILLIS:
189         waitMillis = getLongValue();
190         return true;
191       case WAIT_NANOS:
192         waitNanos = getIntValue();
193         return true;
194       case NOTIFY_ALL:
195         notifyAll = getBooleanValue();
196         return true;
197       case WAIT_ARG_COUNT:
198         waitArgCount = getIntValue();
199         return true;
200       case LOCK_CONTEXT:
201         lockContexts.add(getObject(new LockContext()));
202         return true;
203       case WAIT_CONTEXT:
204         waitContexts.add(getObject(new WaitContext()));
205         return true;
206       case PENDING_LOCK_CONTEXT:
207         pendingLockContexts.add(getObject(new LockContext()));
208         return true;
209       default:
210         return false;
211     }
212   }
213
214   public LockID getLockID() {
215     return lockID;
216   }
217
218   public ThreadID getThreadID() {
219     return threadID;
220   }
221
222   public int getLockLevel() {
223     return lockLevel;
224   }
225
226   public boolean isNotifyAll() {
227     return notifyAll;
228   }
229
230   public void addLockContext(LockContext ctxt) {
231     synchronized (lockContexts) {
232       lockContexts.add(ctxt);
233     }
234   }
235
236   public Collection JavaDoc getLockContexts() {
237     synchronized (lockContexts) {
238       return new HashSet JavaDoc(lockContexts);
239     }
240   }
241
242   public void addWaitContext(WaitContext ctxt) {
243     synchronized (waitContexts) {
244       waitContexts.add(ctxt);
245     }
246   }
247
248   public Collection JavaDoc getWaitContexts() {
249     synchronized (waitContexts) {
250       return new HashSet JavaDoc(waitContexts);
251     }
252   }
253
254   public void addPendingLockContext(LockContext ctxt) {
255     synchronized (pendingLockContexts) {
256       pendingLockContexts.add(ctxt);
257     }
258   }
259
260   public Collection JavaDoc getPendingLockContexts() {
261     synchronized (pendingLockContexts) {
262       return new HashSet JavaDoc(pendingLockContexts);
263     }
264   }
265   
266   public boolean isInterruptWaitRequest() {
267     if (!isValidRequestType(requestType)) { throw new AssertionError JavaDoc("Invalid request type: " + requestType); }
268     return requestType == INTERRUPT_WAIT_REQUEST_TYPE;
269   }
270
271   public boolean isQueryLockRequest() {
272     if (!isValidRequestType(requestType)) { throw new AssertionError JavaDoc("Invalid request type: " + requestType); }
273     return requestType == QUERY_LOCK_REQUEST_TYPE;
274   }
275
276   public boolean isTryObtainLockRequest() {
277     if (!isValidRequestType(requestType)) { throw new AssertionError JavaDoc("Invalid request type: " + requestType); }
278     return requestType == TRY_OBTAIN_LOCK_REQUEST_TYPE;
279   }
280
281   public boolean isObtainLockRequest() {
282     if (!isValidRequestType(requestType)) { throw new AssertionError JavaDoc("Invalid request type: " + requestType); }
283     return requestType == OBTAIN_LOCK_REQUEST_TYPE;
284   }
285
286   public boolean isReleaseLockRequest() {
287     if (!isValidRequestType(requestType)) { throw new AssertionError JavaDoc("Invalid request type: " + requestType); }
288     return requestType == RELEASE_LOCK_REQUEST_TYPE;
289   }
290
291   public boolean isRecallCommitLockRequest() {
292     if (!isValidRequestType(requestType)) { throw new AssertionError JavaDoc("Invalid request type: " + requestType); }
293     return requestType == RECALL_COMMIT_LOCK_REQUEST_TYPE;
294   }
295
296   public WaitInvocation getWaitInvocation() {
297     if (!this.withWait) { throw new IllegalStateException JavaDoc("not a wait request"); }
298     return waitInvocationFactory.newWaitInvocation(this.waitArgCount, this.waitMillis, this.waitNanos);
299   }
300
301   public boolean isWaitRelease() {
302     return this.withWait;
303   }
304
305   public void initializeInterruptWait(LockID lid, ThreadID id) {
306     initialize(lid, id, LockLevel.NIL_LOCK_LEVEL, INTERRUPT_WAIT_REQUEST_TYPE, false, false, UNITIALIZED_WAIT_TIME,
307                UNITIALIZED_WAIT_TIME, -1);
308   }
309
310   public void initializeQueryLock(LockID lid, ThreadID id) {
311     initialize(lid, id, LockLevel.NIL_LOCK_LEVEL, QUERY_LOCK_REQUEST_TYPE, false, false, UNITIALIZED_WAIT_TIME,
312                UNITIALIZED_WAIT_TIME, -1);
313   }
314
315   public void initializeObtainLock(LockID lid, ThreadID id, int type) {
316     initialize(lid, id, type, OBTAIN_LOCK_REQUEST_TYPE, false, false, UNITIALIZED_WAIT_TIME, UNITIALIZED_WAIT_TIME, -1);
317   }
318
319   public void initializeTryObtainLock(LockID lid, ThreadID id, int type) {
320     initialize(lid, id, type, TRY_OBTAIN_LOCK_REQUEST_TYPE, false, false, UNITIALIZED_WAIT_TIME, UNITIALIZED_WAIT_TIME,
321                -1);
322   }
323
324   public void initializeLockRelease(LockID lid, ThreadID id) {
325     initialize(lid, id, LockLevel.NIL_LOCK_LEVEL, RELEASE_LOCK_REQUEST_TYPE, false, false, UNITIALIZED_WAIT_TIME,
326                UNITIALIZED_WAIT_TIME, -1);
327   }
328
329   public void initializeLockReleaseWait(LockID lid, ThreadID id, WaitInvocation call) {
330     initialize(lid, id, LockLevel.NIL_LOCK_LEVEL, RELEASE_LOCK_REQUEST_TYPE, true, false, call.getMillis(), call
331         .getNanos(), call.getSignature().getArgCount());
332   }
333
334   public void initializeLockRecallCommit(LockID lid) {
335     initialize(lid, ThreadID.VM_ID, LockLevel.NIL_LOCK_LEVEL, RECALL_COMMIT_LOCK_REQUEST_TYPE, false, false,
336                UNITIALIZED_WAIT_TIME, UNITIALIZED_WAIT_TIME, -1);
337   }
338
339   private void initialize(LockID lid, ThreadID id, int level, byte reqType, boolean wait, boolean all, long millis,
340                           int nanos, int waitArgs) {
341     this.lockID = lid;
342     this.lockLevel = level;
343     this.threadID = id;
344
345     if (!isValidRequestType(reqType)) { throw new IllegalArgumentException JavaDoc("Invalid request type: " + reqType); }
346     this.requestType = reqType;
347
348     if (this.requestType == RELEASE_LOCK_REQUEST_TYPE || this.requestType == RECALL_COMMIT_LOCK_REQUEST_TYPE) {
349       if (this.lockLevel != LockLevel.NIL_LOCK_LEVEL) {
350         // make the formatter happy
351
throw new IllegalArgumentException JavaDoc("Cannot specify a lock level for release or recall commit(yet)");
352       }
353     }
354
355     this.withWait = wait;
356     this.notifyAll = all;
357
358     if (wait) {
359       if ((waitArgs < 0) || (waitArgs > 2)) { throw new IllegalArgumentException JavaDoc(
360                                                                                  "Wait argument count must be 0, 1 or 2"); }
361
362       if (requestType != RELEASE_LOCK_REQUEST_TYPE) { throw new IllegalArgumentException JavaDoc(
363                                                                                          "Can't include withWait option for non lock release requests"); }
364
365       this.waitArgCount = waitArgs;
366       this.waitMillis = millis;
367       this.waitNanos = nanos;
368     }
369   }
370
371 }
372
Popular Tags