001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
008:
009: import com.tc.object.config.ConfigVisitor;
010: import com.tc.object.config.DSOClientConfigHelper;
011: import com.tc.object.config.TransparencyClassSpec;
012: import com.tc.simulator.app.ApplicationConfig;
013: import com.tc.simulator.listener.ListenerProvider;
014: import com.tc.util.Assert;
015: import com.tctest.runner.AbstractTransparentApp;
016:
017: public class InterruptTestApp extends AbstractTransparentApp {
018: private volatile boolean interruptedFlag = false;
019: private final Object lockObject = new Object();
020: private final SharedData sharedData = new SharedData();
021:
022: private final CyclicBarrier barrier;
023:
024: public InterruptTestApp(String appId, ApplicationConfig cfg,
025: ListenerProvider listenerProvider) {
026: super (appId, cfg, listenerProvider);
027: barrier = new CyclicBarrier(getParticipantCount());
028: }
029:
030: public void run() {
031: try {
032: int index = barrier.barrier();
033: testWaitInterrupt1(index);
034: testWaitInterrupt2(index);
035: testWaitInterrupt3(index);
036: testWaitInterrupt4(index);
037: } catch (Throwable t) {
038: notifyError(t);
039: }
040: }
041:
042: private void testWaitInterrupt1(int index) throws Exception {
043: if (index == 0) {
044: final CyclicBarrier localBarrier = new CyclicBarrier(2);
045: Thread t = new Thread(new Runnable() {
046: public void run() {
047: try {
048: synchronized (lockObject) {
049: localBarrier.barrier();
050: lockObject.wait();
051: throw new AssertionError(
052: "Should have thrown an InterruptedException.");
053: }
054: } catch (InterruptedException e) {
055: interruptedFlag = true;
056: } catch (Throwable e) {
057: notifyError(e);
058: }
059: }
060: });
061: t.start();
062: localBarrier.barrier();
063: t.interrupt();
064: while (!interruptedFlag) {
065: // do nothing
066: }
067: //while (!interruptedFlag && t.isAlive()) {
068: // t.interrupt();
069: // }
070: Assert.assertTrue(interruptedFlag);
071: interruptedFlag = false;
072: }
073: barrier.barrier();
074: }
075:
076: private void testWaitInterrupt2(int index) throws Exception {
077: if (index == 0) {
078: final CyclicBarrier localBarrier = new CyclicBarrier(2);
079: Thread t1 = new Thread(new Runnable() {
080: public void run() {
081: synchronized (lockObject) {
082: try {
083: localBarrier.barrier();
084: lockObject.wait();
085: throw new AssertionError(
086: "Should have thrown an InterruptedException.");
087: } catch (InterruptedException e) {
088: interruptedFlag = true;
089: } catch (Throwable e) {
090: notifyError(e);
091: }
092: }
093: }
094: });
095: Thread t2 = new Thread(new Runnable() {
096: public void run() {
097: synchronized (lockObject) {
098: try {
099: localBarrier.barrier();
100: lockObject.wait();
101: } catch (InterruptedException ie) {
102: interruptedFlag = true;
103: } catch (Throwable t) {
104: notifyError(t);
105: }
106: }
107: }
108: });
109: t1.start();
110: localBarrier.barrier();
111: t2.start();
112: localBarrier.barrier();
113: t1.interrupt();
114: while (!interruptedFlag) {
115: // do nothing
116: }
117: //while (!interruptedFlag && t1.isAlive()) {
118: // t1.interrupt();
119: //}
120: interruptedFlag = false;
121: t2.interrupt();
122: while (!interruptedFlag) {
123: // do nothing
124: }
125: //while (!interruptedFlag && t2.isAlive()) {
126: // t2.interrupt();
127: //}
128: interruptedFlag = false;
129: }
130: barrier.barrier();
131: }
132:
133: private void testWaitInterrupt3(int index) throws Exception {
134: System.err.println("Running test 3");
135: if (index == 0) {
136: final CyclicBarrier localBarrier = new CyclicBarrier(2);
137: Thread t1 = new Thread(new Runnable() {
138: public void run() {
139: synchronized (lockObject) {
140: try {
141: localBarrier.barrier();
142: lockObject.wait();
143: throw new AssertionError(
144: "Should have thrown an InterruptedException.");
145: } catch (InterruptedException e) {
146: interruptedFlag = true;
147: } catch (Throwable e) {
148: notifyError(e);
149: }
150: }
151: }
152: });
153: Thread t2 = new Thread(new Runnable() {
154: public void run() {
155: synchronized (lockObject) {
156: try {
157: localBarrier.barrier();
158: Thread.sleep(10000);
159: } catch (Throwable t) {
160: notifyError(t);
161: }
162: }
163: }
164: });
165: t1.start();
166: localBarrier.barrier();
167: t2.start();
168: localBarrier.barrier();
169: t1.interrupt();
170: while (!interruptedFlag) {
171: // do nothing
172: }
173: //while (!interruptedFlag && t1.isAlive()) {
174: // t1.interrupt();
175: //}
176: interruptedFlag = false;
177: }
178: barrier.barrier();
179: }
180:
181: /**
182: * This test involves 2 nodes. One node goes to wait, while a remote node grabs the lock. The first node
183: * get interrupted, wait for the other node to release the lock and grabs the lock back.
184: */
185: private void testWaitInterrupt4(int index) throws Exception {
186: if (index == 0) {
187: final CyclicBarrier localBarrier = new CyclicBarrier(2);
188: Thread t1 = new Thread(new Runnable() {
189: public void run() {
190: synchronized (lockObject) {
191: try {
192: localBarrier.barrier();
193: lockObject.wait();
194: throw new AssertionError(
195: "Should have thrown an InterruptedException.");
196: } catch (InterruptedException e) {
197: interruptedFlag = true;
198: } catch (Throwable e) {
199: notifyError(e);
200: }
201: Assert.assertEquals(10, sharedData.getData());
202: sharedData.setData(20);
203: }
204: }
205: });
206: t1.start();
207: localBarrier.barrier();
208: barrier.barrier();
209: barrier.barrier();
210: t1.interrupt();
211: while (!interruptedFlag) {
212: // do nothing
213: }
214: //while (!interruptedFlag && t1.isAlive()) {
215: // t1.interrupt();
216: //}
217: interruptedFlag = false;
218: } else {
219: barrier.barrier();
220: synchronized (lockObject) {
221: barrier.barrier();
222: Thread.sleep(10000);
223: sharedData.setData(10);
224: }
225: }
226: barrier.barrier();
227:
228: Assert.assertEquals(20, sharedData.getData());
229:
230: barrier.barrier();
231: }
232:
233: public static void visitL1DSOConfig(ConfigVisitor visitor,
234: DSOClientConfigHelper config) {
235: TransparencyClassSpec spec = config
236: .getOrCreateSpec(CyclicBarrier.class.getName());
237: config.addWriteAutolock("* " + CyclicBarrier.class.getName()
238: + "*.*(..)");
239:
240: String testClass = InterruptTestApp.class.getName();
241: spec = config.getOrCreateSpec(testClass);
242:
243: config.addIncludePattern(testClass + "$*");
244:
245: String methodExpression = "* " + testClass + "*.*(..)";
246: config.addWriteAutolock(methodExpression);
247:
248: spec.addRoot("barrier", "barrier");
249: spec.addRoot("lockObject", "lockObject");
250: spec.addRoot("sharedData", "sharedData");
251: }
252:
253: private static class SharedData {
254: private int data;
255:
256: public int getData() {
257: return data;
258: }
259:
260: public void setData(int data) {
261: this.data = data;
262: }
263: }
264: }
|