001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package threaddemo.locking;
043:
044: import java.awt.EventQueue;
045: import java.io.IOException;
046: import java.lang.reflect.InvocationTargetException;
047: import junit.framework.TestCase;
048: import junit.framework.TestSuite;
049: import junit.textui.TestRunner;
050:
051: /**
052: * Test Locks.eventHybrid.
053: * @author Jesse Glick
054: */
055: public class EventHybridLockTest extends TestCase {
056:
057: public EventHybridLockTest(String name) {
058: super (name);
059: }
060:
061: public void testEventHybrid() throws Exception {
062: assertTrue("Not starting in AWT", !EventQueue
063: .isDispatchThread());
064: // test canRead, canWrite, correct thread used by synch write methods
065: assertTrue(!Locks.eventHybrid().canRead());
066: assertTrue(!Locks.eventHybrid().canWrite());
067: assertTrue(Locks.eventHybrid().read(new LockAction<Boolean>() {
068: public Boolean run() {
069: return !EventQueue.isDispatchThread()
070: && Locks.eventHybrid().canRead()
071: && !Locks.eventHybrid().canWrite();
072: }
073: }));
074: assertTrue(Locks.eventHybrid().read(
075: new LockExceptionAction<Boolean, Exception>() {
076: public Boolean run() throws Exception {
077: return !EventQueue.isDispatchThread()
078: && Locks.eventHybrid().canRead()
079: && !Locks.eventHybrid().canWrite();
080: }
081: }));
082: assertTrue(Locks.eventHybrid().write(new LockAction<Boolean>() {
083: public Boolean run() {
084: return EventQueue.isDispatchThread()
085: && Locks.eventHybrid().canRead()
086: && Locks.eventHybrid().canWrite();
087: }
088: }));
089: assertTrue(Locks.eventHybrid().write(
090: new LockExceptionAction<Boolean, Exception>() {
091: public Boolean run() throws Exception {
092: return EventQueue.isDispatchThread()
093: && Locks.eventHybrid().canRead()
094: && Locks.eventHybrid().canWrite();
095: }
096: }));
097: final boolean[] b = new boolean[1];
098: // Test that while in AWT randomly, can read but not write.
099: EventQueue.invokeAndWait(new Runnable() {
100: public void run() {
101: b[0] = EventQueue.isDispatchThread()
102: && Locks.eventHybrid().canRead()
103: && !Locks.eventHybrid().canWrite();
104: }
105: });
106: assertTrue(b[0]);
107: // While in AWT, can enter read or write directly.
108: EventQueue.invokeAndWait(new Runnable() {
109: public void run() {
110: b[0] = Locks.eventHybrid().read(
111: new LockAction<Boolean>() {
112: public Boolean run() {
113: return EventQueue.isDispatchThread()
114: && Locks.eventHybrid()
115: .canRead()
116: && !Locks.eventHybrid()
117: .canWrite();
118: }
119: });
120: }
121: });
122: assertTrue(b[0]);
123: EventQueue.invokeAndWait(new Runnable() {
124: public void run() {
125: b[0] = Locks.eventHybrid().write(
126: new LockAction<Boolean>() {
127: public Boolean run() {
128: return EventQueue.isDispatchThread()
129: && Locks.eventHybrid()
130: .canRead()
131: && Locks.eventHybrid()
132: .canWrite();
133: }
134: });
135: }
136: });
137: assertTrue(b[0]);
138: }
139:
140: public void testEventHybridLocking() throws Exception {
141: // XXX test locking out readers by writer or vice-versa
142: }
143:
144: public void testEventHybridReadToWriteForbidden() throws Exception {
145: assertTrue("Not starting in AWT", !EventQueue
146: .isDispatchThread());
147: Locks.eventHybrid().read(new LockAction<Void>() {
148: public Void run() {
149: assertTrue(!EventQueue.isDispatchThread());
150: assertTrue(Locks.eventHybrid().canRead());
151: assertTrue(!Locks.eventHybrid().canWrite());
152: try {
153: Locks.eventHybrid().write(new LockAction<Void>() {
154: public Void run() {
155: fail();
156: return null;
157: }
158: });
159: } catch (IllegalStateException e) {
160: // OK.
161: }
162: return null;
163: }
164: });
165: final Error[] err = new Error[1];
166: EventQueue.invokeAndWait(new Runnable() {
167: public void run() {
168: try {
169: Locks.eventHybrid().read(new LockAction<Void>() {
170: public Void run() {
171: assertTrue(EventQueue.isDispatchThread());
172: assertTrue(Locks.eventHybrid().canRead());
173: assertTrue(!Locks.eventHybrid().canWrite());
174: try {
175: Locks.eventHybrid().write(
176: new LockAction<Void>() {
177: public Void run() {
178: fail();
179: return null;
180: }
181: });
182: } catch (IllegalStateException e) {
183: // OK.
184: }
185: return null;
186: }
187: });
188: } catch (Error e) {
189: err[0] = e;
190: }
191: }
192: });
193: if (err[0] != null)
194: throw err[0];
195: Locks.eventHybrid().write(new LockAction<Void>() {
196: public Void run() {
197: assertTrue(Locks.eventHybrid().canWrite());
198: Locks.eventHybrid().read(new LockAction<Void>() {
199: public Void run() {
200: assertTrue(Locks.eventHybrid().canRead());
201: assertTrue(!Locks.eventHybrid().canWrite());
202: try {
203: Locks.eventHybrid().write(
204: new LockAction<Void>() {
205: public Void run() {
206: fail();
207: return null;
208: }
209: });
210: } catch (IllegalStateException e) {
211: // OK.
212: }
213: return null;
214: }
215: });
216: return null;
217: }
218: });
219: }
220:
221: public void testEventHybridWriteToReadPermitted() throws Exception {
222: assertTrue("Not starting in AWT", !EventQueue
223: .isDispatchThread());
224: Locks.eventHybrid().write(new LockAction<Void>() {
225: public Void run() {
226: assertTrue(EventQueue.isDispatchThread());
227: try {
228: Locks.eventHybrid().read(new LockAction<Void>() {
229: public Void run() {
230: // OK.
231: return null;
232: }
233: });
234: } catch (IllegalStateException e) {
235: fail(e.toString());
236: }
237: return null;
238: }
239: });
240: EventQueue.invokeAndWait(new Runnable() {
241: public void run() {
242: Locks.eventHybrid().write(new LockAction<Void>() {
243: public Void run() {
244: assertTrue(EventQueue.isDispatchThread());
245: try {
246: Locks.eventHybrid().read(
247: new LockAction<Void>() {
248: public Void run() {
249: // OK.
250: return null;
251: }
252: });
253: } catch (IllegalStateException e) {
254: fail(e.toString());
255: }
256: return null;
257: }
258: });
259: }
260: });
261: }
262:
263: public void testEventHybridPostedRequests() throws Exception {
264: // XXX postRR, postWR
265: }
266:
267: public void testEventHybridExceptions() throws Exception {
268: assertTrue("Not starting in AWT", !EventQueue
269: .isDispatchThread());
270: // test that checked excs from M.EA throw correct ME
271: try {
272: Locks.eventHybrid().read(
273: new LockExceptionAction<Void, IOException>() {
274: public Void run() throws IOException {
275: throw new IOException();
276: }
277: });
278: fail();
279: } catch (IOException e) {
280: // OK
281: }
282: // but that unchecked excs are passed thru
283: try {
284: Locks.eventHybrid().read(
285: new LockExceptionAction<Void, IOException>() {
286: public Void run() throws IOException {
287: throw new IllegalArgumentException();
288: }
289: });
290: fail();
291: } catch (IllegalArgumentException e) {
292: // OK
293: } catch (IOException e) {
294: fail(e.toString());
295: }
296: // similarly for unchecked excs from M.A
297: try {
298: Locks.eventHybrid().read(new LockAction<Void>() {
299: public Void run() {
300: throw new IllegalArgumentException();
301: }
302: });
303: fail();
304: } catch (IllegalArgumentException e) {
305: // OK
306: } catch (RuntimeException e) {
307: fail(e.toString());
308: }
309: // and blocking runnables
310: try {
311: Locks.eventHybrid().read(new Runnable() {
312: public void run() {
313: throw new IllegalArgumentException();
314: }
315: });
316: fail();
317: } catch (IllegalArgumentException e) {
318: // OK.
319: }
320: try {
321: Locks.eventHybrid().write(new Runnable() {
322: public void run() {
323: throw new IllegalArgumentException();
324: }
325: });
326: fail();
327: } catch (IllegalArgumentException e) {
328: // OK.
329: }
330: }
331:
332: }
|