001: /*
002:
003: Derby - Class org.apache.derbyTesting.unitTests.services.T_LockFactory
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.unitTests.services;
023:
024: import org.apache.derbyTesting.unitTests.harness.T_MultiIterations;
025: import org.apache.derbyTesting.unitTests.harness.T_Fail;
026:
027: import org.apache.derby.iapi.services.locks.*;
028:
029: import org.apache.derby.iapi.services.monitor.Monitor;
030:
031: import org.apache.derby.iapi.reference.SQLState;
032:
033: import org.apache.derby.iapi.error.StandardException;
034:
035: /**
036: Protocol unit test for the LockManager.
037:
038: @see LockFactory
039: @see org.apache.derbyTesting.unitTests.harness..UnitTest
040: */
041:
042: public class T_LockFactory extends T_MultiIterations {
043: protected final static int ITERATIONS = 100; // iterations of multi-user tests
044:
045: protected LockFactory lf;
046:
047: public T_LockFactory() {
048: super ();
049: }
050:
051: /*
052: ** The tests
053: */
054:
055: protected String getModuleToTestProtocolName() {
056:
057: return org.apache.derby.iapi.reference.Module.LockFactory;
058: }
059:
060: /**
061: Run all the tests, each test that starts with 'S' is a single user
062: test, each test that starts with 'M' is a multi-user test.
063:
064: @exception T_Fail The test failed in some way.
065: */
066: protected void setupTest() throws T_Fail {
067:
068: try {
069: lf = (LockFactory) Monitor
070: .startSystemModule(getModuleToTestProtocolName());
071: } catch (StandardException mse) {
072: throw T_Fail.exceptionFail(mse);
073: }
074: if (lf == null) {
075: throw T_Fail.testFailMsg(getModuleToTestProtocolName()
076: + " module not started.");
077: }
078: }
079:
080: /**
081: Run once per-iteration to run the actual test.
082: @exception T_Fail the test failed in some way.
083: */
084: protected void runTestSet() throws T_Fail {
085:
086: // Set up the expected error handling
087: try {
088:
089: S001();
090: S002();
091: S003();
092: S004();
093: S005();
094: S007();
095: S008();
096:
097: M001();
098: M002();
099: M003();
100: M004();
101:
102: } catch (StandardException se) {
103:
104: throw T_Fail.exceptionFail(se);
105:
106: }
107: }
108:
109: /*
110: ** Test functions
111: */
112:
113: /**
114: Single user API test 001.
115:
116: Lock an single object in a single group with all lock methods and
117: then unlock the object with all unlock methods.
118:
119: @exception StandardException An exception thrown by a method of LockFactory
120: @exception T_Fail Some behaviour of the LockFactory is incorrect
121: */
122: void S001() throws StandardException, T_Fail {
123:
124: Object cs = new Object(); // create an object for the compatability space
125: Object g0 = new Object(); // create an object for a lock group
126: Lockable l0 = new T_L1(); // simple lockable
127:
128: int count;
129:
130: // check we have no locks held
131: checkLockCount(cs, 0);
132:
133: // lock and unlock specifically (no timeout)
134: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
135: checkLockCount(cs, 1);
136: count = lf.unlock(cs, g0, l0, null);
137: if (count != 1)
138: throw T_Fail
139: .testFailMsg("invalid unlock count, expected 1, got "
140: + count);
141:
142: // check we have no locks held
143: checkLockCount(cs, 0);
144:
145: // lock twice and unlock all ...
146: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
147: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
148: checkLockCount(cs, 2);
149: lf.unlock(cs, g0, l0, null);
150: lf.unlock(cs, g0, l0, null);
151:
152: // check we have no locks held
153: checkLockCount(cs, 0);
154:
155: // lock three times and unlock by group
156: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
157: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
158: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
159: checkLockCount(cs, 3);
160: lf.unlockGroup(cs, g0);
161:
162: // check we have no locks held
163: checkLockCount(cs, 0);
164:
165: // lock three times and unlock explicitly
166: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
167: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
168: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
169: checkLockCount(cs, 3);
170:
171: lf.unlock(cs, g0, l0, null);
172: checkLockCount(cs, 2);
173:
174: lf.unlock(cs, g0, l0, null);
175: checkLockCount(cs, 1);
176:
177: lf.unlock(cs, g0, l0, null);
178: checkLockCount(cs, 0);
179:
180: // lock and unlock specifically with timeout
181: lf.lockObject(cs, g0, l0, null, 1000 /*ms*/);
182: checkLockCount(cs, 1);
183: count = lf.unlock(cs, g0, l0, null);
184: if (count != 1)
185: throw T_Fail
186: .testFailMsg("invalid unlock count, expected 1, got "
187: + count);
188:
189: PASS("S001");
190: }
191:
192: /**
193: Single user API test 002.
194:
195: Lock an object in different groups and check unlocks
196: apply to a single group.
197:
198: @exception StandardException An exception thrown by a method of LockFactory
199: @exception T_Fail Some behaviour of the LockFactory is incorrect
200: */
201:
202: void S002() throws StandardException, T_Fail {
203:
204: Object cs = new Object(); // create an object for the compatability space
205: Object g0 = new Object(); // create an object for a lock group
206: Object g1 = new Object();
207: Lockable l0 = new T_L1(); // simple lockable
208:
209: int count;
210:
211: // check we have no locks held
212: checkLockCount(cs, 0);
213:
214: // lock object in two groups and unlock specifically
215: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
216: lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
217: checkLockGroupCount(cs, g0, 1);
218: checkLockGroupCount(cs, g1, 1);
219: checkLockCount(cs, 2);
220:
221: count = lf.unlock(cs, g0, l0, null);
222: if (count != 1)
223: throw T_Fail
224: .testFailMsg("invalid unlock count, expected 1, got "
225: + count);
226: checkLockGroupCount(cs, g0, 0);
227: checkLockGroupCount(cs, g1, 1);
228: checkLockCount(cs, 1);
229:
230: count = lf.unlock(cs, g1, l0, null);
231: if (count != 1)
232: throw T_Fail
233: .testFailMsg("invalid unlock count, expected 1, got "
234: + count);
235: checkLockGroupCount(cs, g0, 0);
236: checkLockGroupCount(cs, g1, 0);
237:
238: // check we have no locks held
239: checkLockCount(cs, 0);
240:
241: // lock object in two groups and unlock by group
242: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
243: lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
244: checkLockCount(cs, 2);
245:
246: lf.unlockGroup(cs, g1);
247: checkLockGroupCount(cs, g0, 1);
248: checkLockGroupCount(cs, g1, 0);
249: checkLockCount(cs, 1);
250:
251: lf.unlockGroup(cs, g0);
252: checkLockGroupCount(cs, g0, 0);
253: checkLockGroupCount(cs, g1, 0);
254:
255: // check we have no locks held
256: checkLockCount(cs, 0);
257:
258: PASS("S002");
259: }
260:
261: /**
262: Single user API test 003.
263:
264: Lock multiple objects in different groups and check unlocks
265: apply to a single group.
266:
267: @exception StandardException An exception thrown by a method of LockFactory
268: @exception T_Fail Some behaviour of the LockFactory is incorrect
269:
270: */
271:
272: void S003() throws StandardException, T_Fail {
273:
274: Object cs = new Object(); // create an object for the compatability space
275: Object g0 = new Object(); // create an object for a lock group
276: Object g1 = new Object();
277: Lockable l0 = new T_L1(); // simple lockable
278: Lockable l1 = new T_L1();
279: Lockable l2 = new T_L1();
280:
281: int count;
282:
283: // check we have no locks held
284: checkLockCount(cs, 0);
285:
286: // lock l0 object in two groups and l1,l2 in group l1
287: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
288: lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
289: lf.lockObject(cs, g1, l1, null, C_LockFactory.WAIT_FOREVER);
290: lf.lockObject(cs, g1, l2, null, C_LockFactory.WAIT_FOREVER);
291:
292: checkLockGroupCount(cs, g0, 1);
293: checkLockGroupCount(cs, g1, 3);
294: checkLockCount(cs, 4);
295:
296: // quick check to see that no one is blocked
297: if (lf.anyoneBlocked())
298: throw T_Fail
299: .testFailMsg("anyoneBlocked() returned true on a set of private locks");
300:
301: lf.unlock(cs, g1, l1, null);
302: checkLockGroupCount(cs, g0, 1);
303: checkLockGroupCount(cs, g1, 2);
304: checkLockCount(cs, 3);
305:
306: lf.unlockGroup(cs, g1);
307: checkLockGroupCount(cs, g0, 1);
308: checkLockGroupCount(cs, g1, 0);
309: checkLockCount(cs, 1);
310:
311: lf.unlockGroup(cs, g0);
312: checkLockGroupCount(cs, g0, 0);
313: checkLockGroupCount(cs, g1, 0);
314:
315: // check we have no locks held
316: checkLockCount(cs, 0);
317:
318: PASS("S003");
319: }
320:
321: /**
322: Single user API test 004.
323:
324: Lock multiple objects in different groups and transfer
325: locks between groups.
326:
327: @exception StandardException An exception thrown by a method of LockFactory
328: @exception T_Fail Some behaviour of the LockFactory is incorrect
329: */
330:
331: void S004() throws StandardException, T_Fail {
332:
333: Object cs = new Object(); // create an object for the compatability space
334: Object g0 = new Object(); // create an object for a lock group
335: Object g1 = new Object();
336: Object g2 = new Object();
337: Lockable l0 = new T_L1(); // simple lockable
338: Lockable l1 = new T_L1();
339: Lockable l2 = new T_L1();
340:
341: int count = 0;
342:
343: // check we have no locks held
344: checkLockCount(cs, 0);
345:
346: // lock l0 object in two groups and l1,l2 in group l1
347: lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
348: lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
349: lf.lockObject(cs, g1, l1, null, C_LockFactory.WAIT_FOREVER);
350: lf.lockObject(cs, g1, l2, null, C_LockFactory.WAIT_FOREVER);
351:
352: checkLockGroupCount(cs, g0, 1);
353: checkLockGroupCount(cs, g1, 3);
354: checkLockCount(cs, 4);
355:
356: lf.transfer(cs, g0, g1);
357: checkLockGroupCount(cs, g0, 0);
358: checkLockGroupCount(cs, g1, 4);
359: checkLockCount(cs, 4);
360:
361: // transfer an empty to a non-existent one
362: lf.transfer(cs, g0, g2);
363: checkLockGroupCount(cs, g0, 0);
364: checkLockGroupCount(cs, g1, 4);
365: checkLockGroupCount(cs, g2, 0);
366: checkLockCount(cs, 4);
367:
368: lf.lockObject(cs, g2, l0, null, C_LockFactory.WAIT_FOREVER);
369: checkLockGroupCount(cs, g2, 1);
370: checkLockCount(cs, 5);
371:
372: lf.transfer(cs, g1, g2);
373: checkLockGroupCount(cs, g1, 0);
374: checkLockGroupCount(cs, g2, 5);
375: checkLockCount(cs, 5);
376:
377: lf.transfer(cs, g2, g1);
378: checkLockGroupCount(cs, g1, 5);
379: checkLockGroupCount(cs, g2, 0);
380: checkLockCount(cs, 5);
381:
382: lf.unlockGroup(cs, g2);
383: checkLockGroupCount(cs, g1, 5);
384: checkLockGroupCount(cs, g2, 0);
385: checkLockCount(cs, 5);
386:
387: lf.unlockGroup(cs, g1);
388: checkLockGroupCount(cs, g1, 0);
389: checkLockGroupCount(cs, g2, 0);
390:
391: // check we have no locks held
392: checkLockCount(cs, 0);
393:
394: PASS("S004");
395: }
396:
397: /**
398: Single user API test 005.
399:
400: Create two compatability spaces and ensure that locks
401: block each other out.
402:
403: @exception StandardException An exception thrown by a method of LockFactory
404: @exception T_Fail Some behaviour of the LockFactory is incorrect
405: */
406: void S005() throws StandardException, T_Fail {
407:
408: Object cs0 = new Object(); // create an object for the compatability space
409: Object cs1 = new Object(); // create an object for the compatability space
410:
411: Object g0 = new Object(); // create an object for a lock group
412: Object g1 = new Object(); // create an object for a lock group
413: Lockable l0 = new T_L1();
414: Lockable l1 = new T_L1();
415: Lockable l2 = new T_L1();
416:
417: int count;
418:
419: // check we have no locks held
420: checkLockCount(cs0, 0);
421: checkLockCount(cs1, 0);
422:
423: lf.lockObject(cs0, g0, l0, null, C_LockFactory.WAIT_FOREVER);
424: lf.lockObject(cs1, g1, l1, null, C_LockFactory.WAIT_FOREVER);
425: checkLockCount(cs0, 1);
426: checkLockCount(cs1, 1);
427:
428: lf.lockObject(cs0, g0, l2, null, C_LockFactory.WAIT_FOREVER);
429: checkLockCount(cs0, 2);
430: checkLockCount(cs1, 1);
431:
432: // now attempt to lock l2 in cs1 with a timeout, should fail
433: try {
434: lf.lockObject(cs1, g1, l2, null, 200 /* ms */);
435: throw T_Fail
436: .testFailMsg("lock succeeded on already locked object");
437: } catch (StandardException lfe) {
438: // we are expecting the timout exception, anything else is an error
439: if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT)) {
440: throw lfe;
441: }
442: checkLockCount(cs0, 2);
443: checkLockCount(cs1, 1);
444:
445: }
446:
447: // now unlock the object, and re-attempt the lock
448: lf.unlock(cs0, g0, l2, null);
449: checkLockCount(cs0, 1);
450: checkLockCount(cs1, 1);
451: lf.lockObject(cs1, g1, l2, null, C_LockFactory.WAIT_FOREVER);
452: checkLockCount(cs0, 1);
453: checkLockCount(cs1, 2);
454:
455: lf.unlockGroup(cs0, g0);
456: lf.unlockGroup(cs1, g1);
457: checkLockCount(cs0, 0);
458: checkLockCount(cs1, 0);
459:
460: PASS("S005");
461:
462: }
463:
464: /**
465: Single user API test 007.
466:
467: Tests on groups and compatibility spaces
468: never seen by the lock manager.
469:
470:
471: @exception StandardException An exception thrown by a method of LockFactory
472: @exception T_Fail Some behaviour of the LockFactory is incorrect
473: */
474: void S007() throws StandardException, T_Fail {
475:
476: Object cs = new Object(); // create an object for the compatability space
477: Object g0 = new Object(); // create an object for a lock group
478: Object g1 = new Object(); // create an object for a lock group
479: Lockable l0 = new T_L1();
480:
481: int count;
482:
483: // check we have no locks held
484: checkLockCount(cs, 0);
485: checkLockGroupCount(cs, g0, 0);
486:
487: lf.unlockGroup(cs, g0);
488: lf.unlockGroup(cs, cs);
489: lf.unlock(cs, g0, l0, null);
490:
491: lf.transfer(cs, g0, g1);
492: lf.transfer(cs, g1, g0);
493:
494: if (lf.anyoneBlocked())
495: throw T_Fail
496: .testFailMsg("anyoneBlocked() returned true on an empty space");
497:
498: // check we have no locks held
499: checkLockCount(cs, 0);
500: checkLockGroupCount(cs, g0, 0);
501: checkLockGroupCount(cs, g1, 0);
502:
503: PASS("S007");
504: }
505:
506: /**
507: Single user API test 008.
508:
509: Create two compatability spaces and ensure that locks/latches
510: block each other out.
511:
512: @exception StandardException An exception thrown by a method of LockFactory
513: @exception T_Fail Some behaviour of the LockFactory is incorrect
514: */
515: void S008() throws StandardException, T_Fail {
516:
517: Object cs0 = new Object(); // create an object for the compatability space
518: Object cs1 = new Object(); // create an object for the compatability space
519:
520: Object g0 = new Object();
521: Object g1 = new Object();
522:
523: T_L1 page = new T_L1();
524: Lockable rA = new T_L1();
525: Lockable rB = new T_L1();
526:
527: int count;
528:
529: // Simulate a page/row lock type access
530: lf.latchObject(cs0, page, null, C_LockFactory.WAIT_FOREVER);
531: lf.lockObject(g0, rA, null, C_LockFactory.WAIT_FOREVER,
532: page.latch); // would release the latch if it had to wait
533: lf.unlatch(page.latch);
534:
535: lf.latchObject(cs1, page, null, C_LockFactory.WAIT_FOREVER);
536: lf.lockObject(g1, rB, null, C_LockFactory.WAIT_FOREVER,
537: page.latch); // would release the latch if it had to wait
538:
539: checkLockCount(cs0, 1);
540: checkLockCount(cs1, 2);
541:
542: // this wait should release the latch, while waiting
543: // on lock, but then re-get the latch after the timeout.
544: try {
545: lf.lockObject(g1, rA, null, 5000, page.latch);
546: throw T_Fail
547: .testFailMsg("lock succeeded on already locked object");
548: } catch (StandardException lfe) {
549: // we are expecting the timoeut exception, anything else is an error
550: if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT)) {
551: throw lfe;
552: }
553: checkLockCount(cs0, 1);
554: checkLockCount(cs1, 1);
555: }
556:
557: try {
558: // make sure latch is held
559: lf.latchObject(cs0, page, null, 5000);
560: throw T_Fail
561: .testFailMsg("latch succeeded on already latch object");
562: } catch (StandardException lfe) {
563: // we are expecting timoeut exception, anything else is an error
564: if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT)) {
565: throw lfe;
566: }
567: }
568:
569: lf.unlatch(page.latch);
570:
571: lf.unlock(cs0, g0, rA, null);
572: lf.unlock(cs1, g0, rB, null);
573:
574: PASS("S008");
575:
576: }
577:
578: /*
579: ** Multi-user tests.
580: */
581:
582: /**
583: Multi-user test 001.
584:
585: Create two lockable objects and pass them off to two threads.
586: Each thread will run lock the first object, set its value then lock
587: the second object & set its value, yield and then release the lock
588: on one and then on two. Various checks are made to ensure the
589: values are as expected.
590:
591: @exception StandardException An exception thrown by a method of LockFactory
592: @exception T_Fail Some behaviour of the LockFactory is incorrect
593: */
594:
595: void M001() throws StandardException, T_Fail {
596:
597: Lockable[] locks = new T_L1[2];
598: locks[0] = new T_L1();
599: locks[1] = new T_L1();
600:
601: T_User u1 = new T_User(1, lf, locks, ITERATIONS,
602: 10 * ITERATIONS);
603: T_User u2 = new T_User(1, lf, locks, ITERATIONS,
604: 20 * ITERATIONS);
605: Thread t1 = new Thread(u1);
606: Thread t2 = new Thread(u2);
607:
608: t1.start();
609: t2.start();
610:
611: try {
612: t1.join();
613: t2.join();
614: } catch (InterruptedException ie) {
615: throw T_Fail.exceptionFail(ie);
616: }
617:
618: if (u1.error != null)
619: throw T_Fail.exceptionFail(u1.error);
620: if (u2.error != null)
621: throw T_Fail.exceptionFail(u2.error);
622:
623: PASS("M001");
624: }
625:
626: /**
627: Multi-user test 002
628:
629: Create a single lockable and have three threads lock it, yield and
630: then release it. The single lockable can only have one locker.
631:
632: @exception StandardException An exception thrown by a method of LockFactory
633: @exception T_Fail Some behaviour of the LockFactory is incorrect
634: */
635:
636: void M002() throws StandardException, T_Fail {
637:
638: Lockable[] locks = new T_L1[1];
639: locks[0] = new T_L1();
640:
641: T_User u1 = new T_User(2, lf, locks, ITERATIONS,
642: 10 * ITERATIONS);
643: T_User u2 = new T_User(2, lf, locks, ITERATIONS,
644: 20 * ITERATIONS);
645: T_User u3 = new T_User(2, lf, locks, ITERATIONS,
646: 30 * ITERATIONS);
647: Thread t1 = new Thread(u1);
648: Thread t2 = new Thread(u2);
649: Thread t3 = new Thread(u3);
650:
651: t1.start();
652: t2.start();
653: t3.start();
654:
655: try {
656: t1.join();
657: t2.join();
658: t3.join();
659: } catch (InterruptedException ie) {
660: throw T_Fail.exceptionFail(ie);
661: }
662:
663: if (u1.error != null)
664: throw T_Fail.exceptionFail(u1.error);
665: if (u2.error != null)
666: throw T_Fail.exceptionFail(u2.error);
667: if (u3.error != null)
668: throw T_Fail.exceptionFail(u3.error);
669:
670: PASS("M002");
671: }
672:
673: /**
674: Multi-user test 003
675:
676: Create a single lockable and have three threads lock it, yield and
677: then release it. The single lockable is a semaphore that can have two lockers.
678:
679: @exception StandardException An exception thrown by a method of LockFactory
680: @exception T_Fail Some behaviour of the LockFactory is incorrect
681: */
682:
683: void M003() throws StandardException, T_Fail {
684:
685: Lockable[] locks = new Lockable[1];
686: locks[0] = new T_L2(2);
687:
688: T_User u1 = new T_User(3, lf, locks, ITERATIONS, 0);
689: T_User u2 = new T_User(3, lf, locks, ITERATIONS, 0);
690: T_User u3 = new T_User(3, lf, locks, ITERATIONS, 0);
691: Thread t1 = new Thread(u1);
692: Thread t2 = new Thread(u2);
693: Thread t3 = new Thread(u3);
694:
695: t1.start();
696: t2.start();
697: t3.start();
698:
699: try {
700: t1.join();
701: t2.join();
702: t3.join();
703: } catch (InterruptedException ie) {
704: throw T_Fail.exceptionFail(ie);
705: }
706:
707: if (u1.error != null)
708: throw T_Fail.exceptionFail(u1.error);
709: if (u2.error != null)
710: throw T_Fail.exceptionFail(u2.error);
711: if (u3.error != null)
712: throw T_Fail.exceptionFail(u3.error);
713:
714: PASS("M003");
715: }
716:
717: /**
718: Multi-user test 004
719:
720: As M003 but each thread will lock the object twice, to ensure that
721: lock manager grantes the lock when the compatability space and qualifier
722: match.
723:
724: @exception StandardException An exception thrown by a method of LockFactory
725: @exception T_Fail Some behaviour of the LockFactory is incorrect
726: */
727:
728: void M004() throws StandardException, T_Fail {
729:
730: Lockable[] locks = new Lockable[1];
731: locks[0] = new T_L2(2);
732:
733: T_User u1 = new T_User(4, lf, locks, ITERATIONS, 0);
734: T_User u2 = new T_User(4, lf, locks, ITERATIONS, 0);
735: T_User u3 = new T_User(4, lf, locks, ITERATIONS, 0);
736: Thread t1 = new Thread(u1);
737: Thread t2 = new Thread(u2);
738: Thread t3 = new Thread(u3);
739:
740: t1.start();
741: t2.start();
742: t3.start();
743:
744: try {
745: t1.join();
746: t2.join();
747: t3.join();
748: } catch (InterruptedException ie) {
749: throw T_Fail.exceptionFail(ie);
750: }
751:
752: if (u1.error != null)
753: throw T_Fail.exceptionFail(u1.error);
754: if (u2.error != null)
755: throw T_Fail.exceptionFail(u2.error);
756: if (u3.error != null)
757: throw T_Fail.exceptionFail(u3.error);
758:
759: PASS("M004");
760: }
761:
762: /*
763: ** Utility functions
764: */
765:
766: /**
767: Check to see if the total number of locks we have is as expected.
768:
769: @exception T_Fail Number of locks is not as expected.
770: */
771: void checkLockCount(Object cs, int expected) throws T_Fail {
772: boolean expect = expected != 0;
773: boolean got = lf.areLocksHeld(cs);
774: if (got != expect)
775: throw T_Fail.testFailMsg("Expected lock count (" + expect
776: + "), got (" + got + ")");
777: }
778:
779: /**
780: Check to see if the number of locks in a group we have is as expected.
781:
782: @exception T_Fail Number of locks is not as expected.
783: */
784:
785: void checkLockGroupCount(Object cs, Object group, int expected)
786: throws T_Fail {
787: boolean expect = expected != 0;
788: boolean got = lf.areLocksHeld(cs, group);
789: if (got != expect)
790: throw T_Fail.testFailMsg("Expected lock count (" + expect
791: + "), got (" + got + ")");
792: }
793:
794: }
|