01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
03: * notice. All rights reserved.
04: */
05: package com.tctest.spring.bean;
06:
07: import com.tc.aspectwerkz.proxy.Uuid;
08:
09: public class SharedLockBean implements ISharedLock {
10: // shared variables
11: private int i = 0;
12: private Long firstHolder = null;
13:
14: // variables not shared
15: private volatile transient boolean release = false;
16: private volatile transient boolean holdsSharedLock = false;
17: private final transient Object localLock = new Object();
18: private final transient long localID = System
19: .identityHashCode(this )
20: + Uuid.newUuid();
21:
22: public long getLocalID() {
23: return localID;
24: }
25:
26: public void lockAndMutate() {
27: try {
28: synchronized (this ) {
29: holdsSharedLock = true;
30:
31: if (firstHolder == null) {
32: synchronized (localLock) {
33: firstHolder = new Long(localID);
34: }
35:
36: while (!release) {
37: sleep(100);
38: }
39:
40: } else if (firstHolder.equals(new Long(localID))) {
41: //
42: throw new AssertionError("firstholder was me!");
43: }
44:
45: }
46: } finally {
47: holdsSharedLock = false;
48: }
49: }
50:
51: public boolean sharedLockHeld() {
52: return holdsSharedLock;
53: }
54:
55: public void release() {
56: release = true;
57: }
58:
59: public Long getFirstHolder() {
60: synchronized (localLock) {
61: return firstHolder;
62: }
63: }
64:
65: private void sleep(long millis) {
66: try {
67: Thread.sleep(millis);
68: } catch (InterruptedException e) {
69: throw new RuntimeException(e);
70: }
71: }
72:
73: public void unlockedMutate() {
74: try {
75: i++;
76: } catch (RuntimeException e) {
77: if (e.getClass().getName().equals(
78: "com.tc.object.tx.UnlockedSharedObjectException")) {
79: // expected
80: } else {
81: throw e;
82: }
83: }
84:
85: if (i != 0) {
86: throw new AssertionError("variable changed to " + i);
87: }
88: }
89:
90: public boolean isFirstHolder() {
91: synchronized (localLock) {
92: if (firstHolder == null) {
93: return false;
94: }
95: return firstHolder.longValue() == localID;
96: }
97: }
98: }
|