Source Code Cross Referenced for MutexTest.java in  » IDE-Netbeans » openide » org » openide » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » openide » org.openide.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.openide.util;
0043:
0044:        import java.io.IOException;
0045:        import java.lang.ref.*;
0046:        import java.lang.reflect.InvocationTargetException;
0047:        import java.util.*;
0048:        import java.util.concurrent.atomic.AtomicBoolean;
0049:        import java.util.logging.Level;
0050:        import java.util.logging.Logger;
0051:        import junit.framework.*;
0052:        import org.netbeans.junit.*;
0053:
0054:        public class MutexTest extends NbTestCase {
0055:            Mutex.Privileged p;
0056:            Mutex m;
0057:
0058:            public MutexTest(java.lang.String testName) {
0059:                super (testName);
0060:            }
0061:
0062:            public static Test suite() {
0063:                NbTestSuite suite = new NbTestSuite(MutexTest.class);
0064:
0065:                return suite;
0066:            }
0067:
0068:            /** Sets up the test.
0069:             */
0070:            @Override
0071:            protected void setUp() {
0072:                p = new Mutex.Privileged();
0073:                m = new Mutex(p);
0074:                Mutex.beStrict = true;
0075:            }
0076:
0077:            @Override
0078:            protected Level logLevel() {
0079:                return Level.FINEST;
0080:            }
0081:
0082:            public void testReadWriteRead() throws Exception {
0083:
0084:                final Object lock = new Object();
0085:                final Mutex.Privileged mPriv = new Mutex.Privileged();
0086:                final Mutex tmpMutex = new Mutex(mPriv);
0087:
0088:                synchronized (lock) {
0089:                    mPriv.enterReadAccess();
0090:
0091:                    new Thread() {
0092:                        public void run() {
0093:                            synchronized (lock) {
0094:                                lock.notifyAll();
0095:                            }
0096:                            mPriv.enterWriteAccess();
0097:                            synchronized (lock) {
0098:                                lock.notifyAll();
0099:                                mPriv.exitWriteAccess();
0100:                            }
0101:                        }
0102:                    }.start();
0103:
0104:                    lock.wait();
0105:
0106:                }
0107:                Thread.sleep(100);
0108:
0109:                mPriv.enterReadAccess();
0110:
0111:                mPriv.exitReadAccess();
0112:
0113:                synchronized (lock) {
0114:                    mPriv.exitReadAccess();
0115:                    lock.wait();
0116:                }
0117:            }
0118:
0119:            /** Simple test to execute read access and write access imediatelly.
0120:             */
0121:            public void testPostImmediatelly() {
0122:                State s = new State();
0123:
0124:                m.postReadRequest(s);
0125:
0126:                if (s.state != 1) {
0127:                    fail("Read request not started immediatelly");
0128:                }
0129:
0130:                m.postWriteRequest(s);
0131:
0132:                if (s.state != 2) {
0133:                    fail("Write request not started immediately");
0134:                }
0135:            }
0136:
0137:            /** Behaviour of postWriteRequest is defined by this test.
0138:             */
0139:            public void testPostWriteRequest() {
0140:
0141:                State s = new State();
0142:
0143:                // first enter
0144:                p.enterWriteAccess();
0145:                p.enterReadAccess();
0146:
0147:                m.postWriteRequest(s);
0148:
0149:                if (s.state != 0) {
0150:                    fail("Write request started when we are in read access");
0151:                }
0152:
0153:                p.exitReadAccess();
0154:
0155:                if (s.state != 1) {
0156:                    fail("Write request not run when leaving read access: "
0157:                            + s.state);
0158:                }
0159:
0160:                // exiting
0161:                p.exitWriteAccess();
0162:
0163:                if (s.state != 1) {
0164:                    fail("Run more times?: " + s.state);
0165:                }
0166:            }
0167:
0168:            /** Behaviour of postReadRequest is defined by this test.
0169:             */
0170:            public void testPostReadRequest() {
0171:
0172:                State s = new State();
0173:
0174:                // first enter
0175:                p.enterWriteAccess();
0176:
0177:                m.postReadRequest(s);
0178:
0179:                if (s.state != 0) {
0180:                    fail("Read request started when we are in write access");
0181:                }
0182:
0183:                p.exitWriteAccess();
0184:
0185:                if (s.state != 1) {
0186:                    fail("Read request not run when leaving write access: "
0187:                            + s.state);
0188:                }
0189:
0190:                if (s.state != 1) {
0191:                    fail("Run more times?: " + s.state);
0192:                }
0193:            }
0194:
0195:            /** Test enter from S mode to X mode *
0196:            public void testXtoS() {
0197:                State s = new State ();
0198:                
0199:                p.enterReadAccess ();
0200:                p.enterWriteAccess ();
0201:                s.run();
0202:                p.exitWriteAccess();
0203:                p.exitReadAccess();
0204:                if (s.state != 1) {
0205:                    fail ("Run more times?: " + s.state);
0206:                }
0207:            }
0208:             */
0209:
0210:            /** Tests posting write and read requests while the Mutex is held
0211:             * in X mode and was entered in S mode as well
0212:             */
0213:            public void testPostWriteReadRequests() {
0214:                State s = new State();
0215:
0216:                // first enter
0217:                p.enterWriteAccess();
0218:                p.enterReadAccess();
0219:
0220:                m.postWriteRequest(s);
0221:
0222:                if (s.state != 0) {
0223:                    fail("Write request started when we are in read access");
0224:                }
0225:
0226:                m.postReadRequest(s);
0227:
0228:                if (s.state != 0) {
0229:                    fail("Read request started when we are in write access");
0230:                }
0231:
0232:                p.exitReadAccess();
0233:
0234:                if (s.state != 1) {
0235:                    fail("Write request not run when leaving read access: "
0236:                            + s.state);
0237:                }
0238:
0239:                // exiting
0240:                p.exitWriteAccess();
0241:
0242:                if (s.state != 2) {
0243:                    fail("Read request not run when leaving write access: "
0244:                            + s.state);
0245:                }
0246:
0247:                consistencyCheck();
0248:            }
0249:
0250:            /** Tests simple postWriteRequest */
0251:            public void testSimplePostWriteRequest() {
0252:                State s = new State();
0253:
0254:                m.postWriteRequest(s);
0255:
0256:                if (s.state != 1) {
0257:                    fail("Write request not run: " + s.state);
0258:                }
0259:
0260:                consistencyCheck();
0261:            }
0262:
0263:            /** Tests simple postReadRequest */
0264:            public void testSimplePostReadRequest() {
0265:                State s = new State();
0266:
0267:                m.postReadRequest(s);
0268:
0269:                if (s.state != 1) {
0270:                    fail("Read request not run: " + s.state);
0271:                }
0272:
0273:                consistencyCheck();
0274:            }
0275:
0276:            // starts a new thread, after return the thread will hold lock "p" in
0277:            // mode X for timeout milliseconds
0278:            private static void asyncEnter(final Mutex.Privileged p,
0279:                    final boolean X, final long timeout)
0280:                    throws InterruptedException {
0281:                asyncEnter(p, X, timeout, null);
0282:            }
0283:
0284:            // starts a new thread, after return the thread will hold lock "p" in
0285:            // mode X for timeout milliseconds, the new thread execs "run" first
0286:            private static void asyncEnter(final Mutex.Privileged p,
0287:                    final boolean X, final long timeout, final Runnable run)
0288:                    throws InterruptedException {
0289:                final Object lock = new Object();
0290:
0291:                synchronized (lock) {
0292:                    new Thread(new Runnable() {
0293:                        public void run() {
0294:                            if (X) {
0295:                                p.enterWriteAccess();
0296:                            } else {
0297:                                p.enterReadAccess();
0298:                            }
0299:
0300:                            synchronized (lock) {
0301:                                lock.notify();
0302:                            }
0303:
0304:                            if (run != null) {
0305:                                run.run();
0306:                            }
0307:
0308:                            try {
0309:                                Thread.sleep(timeout);
0310:                            } catch (InterruptedException e) {
0311:                                e.printStackTrace();
0312:                            }
0313:
0314:                            if (X) {
0315:                                p.exitWriteAccess();
0316:                            } else {
0317:                                p.exitReadAccess();
0318:                            }
0319:
0320:                        }
0321:                    }).start();
0322:
0323:                    lock.wait();
0324:                }
0325:            }
0326:
0327:            /** Tests enterWriteAccess while the Mutex is contended in X mode by
0328:             * another thread
0329:             */
0330:            public void testXContendedX() throws InterruptedException {
0331:                asyncEnter(p, true, 2000);
0332:
0333:                // first enter
0334:                p.enterWriteAccess();
0335:                p.exitWriteAccess();
0336:
0337:                consistencyCheck();
0338:            }
0339:
0340:            /** Tests enterReadAccess while the Mutex is contended in X mode by
0341:             * another thread
0342:             */
0343:            public void testXContendedS() throws InterruptedException {
0344:                asyncEnter(p, true, 2000);
0345:
0346:                // first enter
0347:                p.enterReadAccess();
0348:                p.exitReadAccess();
0349:
0350:                consistencyCheck();
0351:            }
0352:
0353:            /** Tests enterWriteAccess while the Mutex is contended in S mode by
0354:             * another thread
0355:             */
0356:            public void testSContendedX() throws InterruptedException {
0357:                asyncEnter(p, false, 2000);
0358:
0359:                // first enter
0360:                p.enterWriteAccess();
0361:                p.exitWriteAccess();
0362:
0363:                consistencyCheck();
0364:            }
0365:
0366:            /** Tests enterReadAccess while the Mutex is contended in S mode by
0367:             * another thread
0368:             */
0369:            public void testSContendedS() throws InterruptedException {
0370:                asyncEnter(p, false, 2000);
0371:
0372:                // first enter
0373:                p.enterReadAccess();
0374:                p.exitReadAccess();
0375:
0376:                consistencyCheck();
0377:            }
0378:
0379:            /** Tests postWriteRequest while the Mutex is contended in X mode by
0380:             * another thread
0381:             */
0382:            public void testXContendedPx() throws InterruptedException {
0383:                asyncEnter(p, true, 2000);
0384:
0385:                State s = new State();
0386:
0387:                m.postWriteRequest(s);
0388:
0389:                if (s.state != 1) {
0390:                    fail("Write request not run: " + s.state);
0391:                }
0392:
0393:                consistencyCheck();
0394:            }
0395:
0396:            /** Tests postReadRequest while the Mutex is contended in X mode by
0397:             * another thread
0398:             */
0399:            public void testXContendedPs() throws InterruptedException {
0400:                asyncEnter(p, true, 2000);
0401:
0402:                State s = new State();
0403:
0404:                m.postReadRequest(s);
0405:
0406:                if (s.state != 1) {
0407:                    fail("Read request not run: " + s.state);
0408:                }
0409:
0410:                consistencyCheck();
0411:            }
0412:
0413:            /** Tests postWriteRequest while the Mutex is contended in S mode by
0414:             * another thread
0415:             */
0416:            public void testSContendedPx() throws InterruptedException {
0417:                asyncEnter(p, false, 2000);
0418:
0419:                State s = new State();
0420:
0421:                m.postWriteRequest(s);
0422:
0423:                if (s.state != 1) {
0424:                    fail("Write request not run: " + s.state);
0425:                }
0426:
0427:                consistencyCheck();
0428:            }
0429:
0430:            /** Tests postReadRequest while the Mutex is contended in S mode by
0431:             * another thread
0432:             */
0433:            public void testSContendedPs() throws InterruptedException {
0434:                asyncEnter(p, false, 2000);
0435:
0436:                State s = new State();
0437:
0438:                m.postReadRequest(s);
0439:
0440:                if (s.state != 1) {
0441:                    fail("Write request not run: " + s.state);
0442:                }
0443:
0444:                consistencyCheck();
0445:            }
0446:
0447:            /** Tests postWriteRequest and postReadRequest while the Mutex is contended in S mode by
0448:             * another thread as well as this thread.
0449:             */
0450:            public void testSContendedSPsPx() throws InterruptedException {
0451:                asyncEnter(p, false, 2000);
0452:
0453:                State s = new State();
0454:
0455:                p.enterReadAccess();
0456:                m.postReadRequest(s);
0457:
0458:                if (s.state != 1) {
0459:                    fail("Read request not run: " + s.state);
0460:                }
0461:
0462:                m.postWriteRequest(s);
0463:
0464:                if (s.state != 1) {
0465:                    fail("Write request run: " + s.state);
0466:                }
0467:
0468:                p.exitReadAccess();
0469:
0470:                if (s.state != 2) {
0471:                    fail("Write request not run: " + s.state);
0472:                }
0473:
0474:                consistencyCheck();
0475:            }
0476:
0477:            /** The Mutex is held in S mode by a thread which also posted a
0478:             * write request. Another thread tries enterWriteAccess.
0479:             */
0480:            public void testSPxContendedX() throws Exception {
0481:                final State s = new State();
0482:
0483:                asyncEnter(p, false, 2000, new Runnable() {
0484:                    public void run() {
0485:                        try {
0486:                            Thread.sleep(1000);
0487:                        } catch (Exception e) {
0488:                            e.printStackTrace();
0489:                        }
0490:                        m.postWriteRequest(s);
0491:                        if (s.state == 1) {
0492:                            fail("Write request run: " + s.state);
0493:                        }
0494:                    }
0495:                });
0496:
0497:                p.enterWriteAccess();
0498:                if (s.state != 1) {
0499:                    fail("Write request not run: " + s.state);
0500:                }
0501:                p.exitWriteAccess();
0502:
0503:                consistencyCheck();
0504:            }
0505:
0506:            /**
0507:             * Test case for #16577. Grab X,S and post X request,
0508:             * the second thread waits for X, causing the mutex to be 
0509:             * in CHAINED.
0510:             */
0511:            public void testXSPxContendedX() throws Exception {
0512:                final State s = new State();
0513:
0514:                asyncEnter(p, true, 2000, new Runnable() {
0515:                    public void run() {
0516:                        p.enterReadAccess();
0517:                        try {
0518:                            Thread.sleep(1000);
0519:                        } catch (Exception e) {
0520:                            e.printStackTrace();
0521:                        }
0522:                        m.postWriteRequest(s);
0523:                        p.exitReadAccess();
0524:
0525:                        if (s.state != 1) {
0526:                            fail("Write request not run: " + s.state);
0527:                        }
0528:                    }
0529:                });
0530:
0531:                p.enterWriteAccess();
0532:                p.exitWriteAccess();
0533:
0534:                consistencyCheck();
0535:            }
0536:
0537:            /**
0538:             * The scenario:
0539:             * Cast:
0540:             *  Thread A: M.reader [X] trying to lock(L)
0541:             *  Thread B: L owner [X] trying to enter M.read
0542:             *  Thread C: M.reader trying to M.writeReenter on leave
0543:             * 
0544:             * Actions:
0545:             *  - first let A and B reach point [X]
0546:             *  - unfuse A so it block on lock(L)
0547:             *  - start C, it will reach exitReadAccess and block on reenter as writer
0548:             *  - unfuse B so it should perform its legitimate read access
0549:             *
0550:             * What should happen then (if Mutex works OK):
0551:             * - B unlocks L and die
0552:             * - A locks/unlocks L, leave readAccess and die
0553:             * - C performs its write and die
0554:             */
0555:            public void testStarvation68106() throws Exception {
0556:                final Mutex.Privileged PR = new Mutex.Privileged();
0557:                final Mutex M = new Mutex(PR);
0558:                final Object L = new Object();
0559:                final boolean[] done = new boolean[3];
0560:
0561:                final Ticker tickX1 = new Ticker();
0562:                final Ticker tickX2 = new Ticker();
0563:                final Ticker tickX3 = new Ticker();
0564:
0565:                Thread A = new Thread("A") {
0566:                    public @Override
0567:                    void run() {
0568:                        PR.enterReadAccess();
0569:
0570:                        tickX1.tick();
0571:                        tickX2.waitOn();
0572:
0573:                        synchronized (L) {
0574:                            done[0] = true;
0575:                        }
0576:
0577:                        PR.exitReadAccess();
0578:                    }
0579:                };
0580:
0581:                Thread B = new Thread("B") {
0582:                    public @Override
0583:                    void run() {
0584:                        synchronized (L) {
0585:
0586:                            tickX2.tick();
0587:                            tickX3.tick();
0588:                            tickX1.waitOn();
0589:
0590:                            PR.enterReadAccess();
0591:                            done[1] = true;
0592:                            PR.exitReadAccess();
0593:                        }
0594:                    }
0595:                };
0596:
0597:                Thread C = new Thread("C") {
0598:                    public @Override
0599:                    void run() {
0600:                        PR.enterReadAccess();
0601:                        M.postWriteRequest(new Runnable() {
0602:                            public void run() {
0603:                                done[2] = true;
0604:                            }
0605:                        });
0606:                        PR.exitReadAccess();
0607:                    }
0608:                };
0609:
0610:                A.start();
0611:                tickX1.waitOn();
0612:                // A reached point X
0613:
0614:                B.start();
0615:                tickX3.waitOn();
0616:                // B reached point X, unlocked A so in would block on lock(L)
0617:
0618:                C.start();
0619:                Thread.sleep(100); // wait for C to perform exitReadAccess (can't
0620:                // tick as it will block in case of failure...)
0621:
0622:                tickX1.tick();
0623:                // push B, everything should finish after this
0624:
0625:                // wait for them for a while
0626:                A.join(2000);
0627:                B.join(2000);
0628:                C.join(2000);
0629:
0630:                if (!done[0] || !done[1] || !done[2]) {
0631:                    StringBuffer sb = new StringBuffer();
0632:                    sb.append("A: ");
0633:                    sb.append(done[0]);
0634:                    sb.append(" B: ");
0635:                    sb.append(done[1]);
0636:                    sb.append(" C: ");
0637:                    sb.append(done[2]);
0638:                    sb.append("\n");
0639:                    dumpStrackTrace(A, sb);
0640:                    dumpStrackTrace(B, sb);
0641:                    dumpStrackTrace(C, sb);
0642:
0643:                    fail(sb.toString());
0644:                }
0645:            }
0646:
0647:            /**
0648:             * The scenario:
0649:             * - Have 3 threads, A, B and C
0650:             * - writeLock mutex1 in A
0651:             * - writeLock mutex2 in B
0652:             *   - postReadLock mutex2 in B
0653:             *     - writeLock mutex1 in B
0654:             * - writeLock mutex2 in C
0655:             *   - readLock mutex2 in A
0656:             * - leaveWriteLock mutex2 in B
0657:             *
0658:             */
0659:            public void testStarvation49466() throws Exception {
0660:                final Mutex.Privileged pr1 = new Mutex.Privileged();
0661:                final Mutex mutex1 = new Mutex(pr1);
0662:
0663:                final Mutex.Privileged pr2 = new Mutex.Privileged();
0664:                final Mutex mutex2 = new Mutex(pr2);
0665:
0666:                final boolean[] done = new boolean[3];
0667:
0668:                final Ticker tick0 = new Ticker();
0669:                final Ticker tick1 = new Ticker();
0670:                final Ticker tick2 = new Ticker();
0671:                final Ticker tick3 = new Ticker();
0672:
0673:                Thread A = new Thread() {
0674:                    public @Override
0675:                    void run() {
0676:                        pr1.enterWriteAccess();
0677:                        tick0.tick();
0678:
0679:                        tick1.waitOn();
0680:
0681:                        pr2.enterReadAccess();
0682:                        done[0] = true;
0683:                        pr2.exitReadAccess();
0684:
0685:                        pr1.exitWriteAccess();
0686:                    }
0687:                };
0688:
0689:                // writeLock mutex1 in A
0690:                A.start();
0691:                tick0.waitOn();
0692:
0693:                Thread B = new Thread() {
0694:                    public @Override
0695:                    void run() {
0696:                        pr2.enterWriteAccess();
0697:
0698:                        mutex2.postReadRequest(new Runnable() {
0699:                            public void run() {
0700:                                tick0.tick();
0701:                                pr1.enterWriteAccess();
0702:                                done[1] = true;
0703:                                pr1.exitWriteAccess();
0704:                            }
0705:                        });
0706:
0707:                        tick0.tick();
0708:
0709:                        tick2.waitOn();
0710:
0711:                        pr2.exitWriteAccess();
0712:                    }
0713:                };
0714:
0715:                // writeLock mutex2 in B
0716:                B.start();
0717:                tick0.waitOn();
0718:
0719:                /*
0720:                 * The test fails even when using only first two threads.
0721:                 *
0722:                 Thread C = new Thread() {
0723:                 public void run() {
0724:                 tick0.tick(); // have to tick in advance and wait :-(
0725:                 pr2.enterWriteAccess();
0726:                 done[2] = true;
0727:                 pr2.exitWriteAccess();
0728:                 }        
0729:                 };
0730:                
0731:                 // writeLock mutex2 in C
0732:                 C.start();
0733:                 tick0.waitOn();
0734:                 Thread.sleep(1000); // between tick and C enqueued ...
0735:                 */
0736:
0737:                // readLock mutex2 in A
0738:                tick1.tick(); // enqueues A in mutex2's queue
0739:                Thread.sleep(1000); // between tick and A enqueued ...
0740:
0741:                // leaveWriteLock mutex2 in B
0742:                tick2.tick();
0743:
0744:                //  postReadLock mutex2 in B
0745:                tick0.waitOn();
0746:
0747:                // System.err.println("Do a thread dump now!");
0748:                Thread.sleep(2000); // give them some time ...
0749:
0750:                assertTrue("Thread A finished", done[0]);
0751:                assertTrue("Thread B finished", done[1]);
0752:
0753:                //        assertTrue("Thread C succeed", done[2]);
0754:            }
0755:
0756:            public void testReadEnterAfterPostWriteWasContended87932()
0757:                    throws Exception {
0758:                final Logger LOG = Logger.getLogger("org.openide.util.test");//testReadEnterAfterPostWriteWasContended87932");
0759:
0760:                final Mutex.Privileged pr = new Mutex.Privileged();
0761:                final Mutex mutex = new Mutex(pr);
0762:                final Ticker tick = new Ticker();
0763:                class WR implements  Runnable {
0764:                    boolean inWrite;
0765:
0766:                    public void run() {
0767:                        inWrite = true;
0768:                        // just keep the write lock for a while
0769:                        MutexTest.sleep(1000);
0770:                        inWrite = false;
0771:                    }
0772:                }
0773:                WR wr = new WR();
0774:
0775:                class T extends Thread {
0776:                    public T() {
0777:                        super (
0778:                                "testReadEnterAfterPostWriteWasContended87932-reader");
0779:                    }
0780:
0781:                    @Override
0782:                    public void run() {
0783:                        pr.enterReadAccess();
0784:                        tick.tick();
0785:
0786:                        // wait for exploitable place in Mutex
0787:                        LOG.log(Level.FINE,
0788:                                "wait for exploitable place in Mutex");
0789:
0790:                        pr.exitReadAccess();
0791:
0792:                        //Let the othe thread continue
0793:                        LOG.log(Level.FINE, "Let the other thread continue");
0794:
0795:                        // the writer gets in now, lets' give him some time.
0796:                        MutexTest.sleep(50);
0797:                        pr.enterReadAccess();
0798:                        //                if (inWrite.get()) fail("Another reader inside while writer keeps lock");
0799:                        pr.exitReadAccess();
0800:
0801:                    }
0802:                }
0803:
0804:                Thread t = new T();
0805:                String str = "THREAD:testReadEnterAfterPostWriteWasContended87932-reader MSG:wait for exploitable place in Mutex"
0806:                        + "THREAD:main MSG:.*Processing posted requests: 2"
0807:                        + "THREAD:testReadEnterAfterPostWriteWasContended87932-reader MSG:Let the other thread continue";
0808:                Log.controlFlow(Logger.getLogger("org.openide.util"), null,
0809:                        str, 100);
0810:
0811:                pr.enterReadAccess();
0812:                t.start();
0813:
0814:                tick.waitOn();
0815:
0816:                mutex.postWriteRequest(wr);
0817:                pr.exitReadAccess();
0818:
0819:                t.join(10000);
0820:            }
0821:
0822:            private static class Ticker {
0823:                boolean state;
0824:
0825:                public void waitOn() {
0826:                    synchronized (this ) {
0827:                        while (!state) {
0828:                            try {
0829:                                wait();
0830:                            } catch (InterruptedException e) {
0831:                                throw new InternalError();
0832:                            }
0833:                        }
0834:                        state = false; // reusable
0835:                    }
0836:                }
0837:
0838:                public void tick() {
0839:                    synchronized (this ) {
0840:                        state = true;
0841:                        notifyAll();
0842:                    }
0843:                }
0844:            }
0845:
0846:            /**
0847:             * Grab X and post S request,
0848:             * the second thread waits for X, causing the mutex to be 
0849:             * in CHAINED.
0850:             */
0851:            public void testXPsContendedX() throws Exception {
0852:                final State s = new State();
0853:
0854:                asyncEnter(p, true, 2000, new Runnable() {
0855:                    public void run() {
0856:                        try {
0857:                            Thread.sleep(1000);
0858:                        } catch (Exception e) {
0859:                            e.printStackTrace();
0860:                        }
0861:                        m.postReadRequest(s);
0862:
0863:                        if (s.state == 1) {
0864:                            fail("Read request run: " + s.state);
0865:                        }
0866:                    }
0867:                });
0868:
0869:                p.enterWriteAccess();
0870:                Thread.sleep(4000);
0871:                p.exitWriteAccess();
0872:
0873:                consistencyCheck();
0874:            }
0875:
0876:            /** Checks the Mutex is in the consistent state, i.e. enterWriteAccess must pass */
0877:            private void consistencyCheck() {
0878:                p.enterWriteAccess();
0879:                p.exitWriteAccess();
0880:            }
0881:
0882:            public void testNoWayToDoReadAndThenWrite() {
0883:                class R implements  Runnable {
0884:                    public void run() {
0885:                        m.writeAccess(this );
0886:                    }
0887:                }
0888:
0889:                try {
0890:                    m.readAccess(new R());
0891:                    fail("This is supposed to throw an IllegalStateException");
0892:                } catch (IllegalStateException ex) {
0893:                    // ok, this is expected
0894:                }
0895:            }
0896:
0897:            public void testNoWayToDoWriteThenReadAndThenWrite() {
0898:                class R implements  Runnable {
0899:                    public boolean second;
0900:                    public boolean end;
0901:                    public boolean ending;
0902:
0903:                    public void run() {
0904:                        if (end) {
0905:                            ending = true;
0906:                            return;
0907:                        }
0908:
0909:                        if (second) {
0910:                            end = true;
0911:                            m.writeAccess(this );
0912:                        } else {
0913:                            second = true;
0914:                            m.readAccess(this );
0915:                        }
0916:                    }
0917:                }
0918:                R r = new R();
0919:                try {
0920:                    m.writeAccess(r);
0921:                    fail("This is supposed to throw an IllegalStateException");
0922:                } catch (IllegalStateException ex) {
0923:                    // ok, this is expected
0924:                    assertTrue("We were in the write access section", r.second);
0925:                    assertTrue("We were before the writeAcess(this)", r.end);
0926:                    assertFalse("We never reached ending", r.ending);
0927:                }
0928:            }
0929:
0930:            public void testIsOrIsNotInReadOrWriteAccess() {
0931:                new ReadWriteChecking("No r/w", Boolean.FALSE, Boolean.FALSE)
0932:                        .run();
0933:                m.readAccess(new ReadWriteChecking("r but no w", Boolean.TRUE,
0934:                        Boolean.FALSE));
0935:                m.writeAccess(new ReadWriteChecking("w but no r",
0936:                        Boolean.FALSE, Boolean.TRUE));
0937:                m.readAccess(new Runnable() {
0938:                    public void run() {
0939:                        m.postReadRequest(new ReadWriteChecking("+r -w",
0940:                                Boolean.TRUE, Boolean.FALSE));
0941:                    }
0942:                });
0943:                m.readAccess(new Runnable() {
0944:                    public void run() {
0945:                        m.postWriteRequest(new ReadWriteChecking("-r +w",
0946:                                Boolean.FALSE, Boolean.TRUE));
0947:                    }
0948:                });
0949:                m.writeAccess(new Runnable() {
0950:                    public void run() {
0951:                        m.postReadRequest(new ReadWriteChecking("+r -w",
0952:                                Boolean.TRUE, Boolean.FALSE));
0953:                    }
0954:                });
0955:                m.writeAccess(new Runnable() {
0956:                    public void run() {
0957:                        m.postWriteRequest(new ReadWriteChecking("-r +w",
0958:                                Boolean.FALSE, Boolean.TRUE));
0959:                    }
0960:                });
0961:
0962:                // write->read->test (downgrade from write to read)
0963:                m.writeAccess(new Runnable() {
0964:                    public boolean second;
0965:
0966:                    public void run() {
0967:                        if (!second) {
0968:                            second = true;
0969:                            m.readAccess(this );
0970:                            return;
0971:                        }
0972:
0973:                        class P implements  Runnable {
0974:                            public boolean exec;
0975:
0976:                            public void run() {
0977:                                exec = true;
0978:                            }
0979:                        }
0980:                        P r = new P();
0981:                        P w = new P();
0982:                        m.postWriteRequest(w);
0983:                        m.postReadRequest(r);
0984:                        assertFalse("Writer not executed", w.exec);
0985:                        assertFalse("Reader not executed", r.exec);
0986:
0987:                        m.readAccess(new ReadWriteChecking("+r +w",
0988:                                Boolean.TRUE, Boolean.TRUE));
0989:                    }
0990:                });
0991:
0992:                new ReadWriteChecking("None at the end", Boolean.FALSE,
0993:                        Boolean.FALSE).run();
0994:            }
0995:
0996:            // [pnejedly:] There was an attempt to fix Starvation68106 by allowing read
0997:            // enter while Mutex is currently in CHAIN mode, but that's wrong, as it can
0998:            // be CHAIN/W (write granted, readers waiting). Let's cover this with a test.
0999:            public void testReaderCannotEnterWriteChainedMutex()
1000:                    throws Exception {
1001:                final Mutex.Privileged PR = new Mutex.Privileged();
1002:                final Mutex M = new Mutex(PR);
1003:                final boolean[] done = new boolean[2];
1004:
1005:                final Ticker tickX1 = new Ticker();
1006:                final Ticker tickX2 = new Ticker();
1007:                final Ticker tickX3 = new Ticker();
1008:
1009:                PR.enterWriteAccess();
1010:
1011:                Thread A = new Thread("A") {
1012:                    public @Override
1013:                    void run() {
1014:                        PR.enterReadAccess();
1015:                        done[0] = true;
1016:                        PR.exitReadAccess();
1017:                    }
1018:                };
1019:
1020:                Thread B = new Thread("B") {
1021:                    public @Override
1022:                    void run() {
1023:                        PR.enterReadAccess();
1024:                        done[1] = true;
1025:                        PR.exitReadAccess();
1026:                    }
1027:                };
1028:
1029:                A.start();
1030:                Thread.sleep(100); // wait for A to chain in M
1031:
1032:                B.start();
1033:                Thread.sleep(100); // B should chain as well
1034:
1035:                assertFalse("B should chain-wait", done[1]);
1036:
1037:                // final cleanup and consistency check:
1038:                PR.exitWriteAccess();
1039:                A.join(1000);
1040:                B.join(1000);
1041:                assertTrue("A finished after unblocking M", done[0]);
1042:                assertTrue("B finished after unblocking M", done[1]);
1043:            }
1044:
1045:            public void testIsReadOrWriteForEventMutex() throws Exception {
1046:                class DoTheWork implements  Runnable {
1047:                    public boolean isRead;
1048:                    public boolean isWrite;
1049:
1050:                    public void run() {
1051:                        isRead = Mutex.EVENT.isReadAccess();
1052:                        isWrite = Mutex.EVENT.isWriteAccess();
1053:                    }
1054:                }
1055:
1056:                DoTheWork rp = new DoTheWork();
1057:                org.openide.util.RequestProcessor.getDefault().post(rp)
1058:                        .waitFinished();
1059:
1060:                DoTheWork awt = new DoTheWork();
1061:                javax.swing.SwingUtilities.invokeAndWait(awt);
1062:
1063:                assertFalse("Nothing in RP", rp.isRead);
1064:                assertFalse("No in RP", rp.isWrite);
1065:
1066:                assertTrue("Is read in ", awt.isRead);
1067:                assertTrue("is also write", awt.isWrite);
1068:            }
1069:
1070:            private void exceptionsReporting(final Throwable t)
1071:                    throws Exception {
1072:                final IOException e1 = new IOException();
1073:                final Mutex mm = m;
1074:                final Runnable secondRequest = new Runnable() {
1075:                    public void run() {
1076:                        if (t instanceof  RuntimeException) {
1077:                            throw (RuntimeException) t;
1078:                        } else {
1079:                            throw (Error) t;
1080:                        }
1081:                    }
1082:                };
1083:                Mutex.ExceptionAction<Object> firstRequest = new Mutex.ExceptionAction<Object>() {
1084:                    public Object run() throws Exception {
1085:                        mm.postWriteRequest(secondRequest);
1086:                        throw e1;
1087:                    }
1088:                };
1089:                try {
1090:                    m.readAccess(firstRequest);
1091:                } catch (MutexException mu) {
1092:                    Exception e = mu.getException();
1093:                    assertEquals("IOException correctly reported", e, e1);
1094:                    return;
1095:                } catch (Throwable e) {
1096:                    fail("a problem in postWriteRequest() should not swallow any "
1097:                            + "exception thrown in readAccess() because that might be "
1098:                            + "the cause of the problem. " + e.toString());
1099:                }
1100:                fail("should never get here");
1101:            }
1102:
1103:            public void testThrowingAssertionErrorInSpecialCase()
1104:                    throws Exception {
1105:                exceptionsReporting(new AssertionError());
1106:            }
1107:
1108:            public void testThrowingRuntimeExceptionInSpecialCase()
1109:                    throws Exception {
1110:                exceptionsReporting(new RuntimeException());
1111:            }
1112:
1113:            private void dumpStrackTrace(Thread thread, StringBuffer sb)
1114:                    throws IllegalAccessException, InvocationTargetException {
1115:                sb.append("StackTrace for thread: " + thread.getName() + "\n");
1116:
1117:                StackTraceElement[] arr = thread.getStackTrace();
1118:
1119:                for (int i = 0; i < arr.length; i++) {
1120:                    sb.append(arr[i].toString());
1121:                    sb.append("\n");
1122:                }
1123:            }
1124:
1125:            private class ReadWriteChecking implements  Runnable {
1126:                public Boolean read;
1127:                public Boolean write;
1128:                public String msg;
1129:
1130:                public ReadWriteChecking(String msg, Boolean read, Boolean write) {
1131:                    assertNotNull("Msg cannot be null", msg);
1132:                    this .msg = msg;
1133:                    this .read = read;
1134:                    this .write = write;
1135:                }
1136:
1137:                @Override
1138:                protected void finalize() {
1139:                    assertNull("Run method was not called!", msg);
1140:                }
1141:
1142:                public void run() {
1143:                    if (write != null)
1144:                        assertEquals(msg, write.booleanValue(), m
1145:                                .isWriteAccess());
1146:                    if (read != null)
1147:                        assertEquals(msg, read.booleanValue(), m.isReadAccess());
1148:                    msg = null;
1149:                }
1150:            }
1151:
1152:            private static class State implements  Runnable {
1153:                public int state;
1154:
1155:                public void run() {
1156:                    state++;
1157:                }
1158:
1159:            } // end of State            
1160:
1161:            private static final void sleep(long ms) {
1162:                try {
1163:                    Thread.sleep(ms);
1164:                } catch (InterruptedException ex) {
1165:                    ex.printStackTrace();
1166:                }
1167:            }
1168:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.