Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 /*
     19  * Entry point and tests that are expected to succeed.
     20  */
     21 public class Main {
     22     /**
     23      * Drives tests.
     24      */
     25     public static void main(String[] args) {
     26         Main m = new Main();
     27 
     28         m.recursiveSync(0);
     29 
     30         m.nestedMayThrow(false);
     31         try {
     32             m.nestedMayThrow(true);
     33             System.err.println("nestedThrow(true) did not throw");
     34         } catch (MyException me) {}
     35         System.out.println("nestedMayThrow ok");
     36 
     37         m.constantLock();
     38         System.out.println("constantLock ok");
     39 
     40         m.notExcessiveNesting();
     41         if (false) {    // TODO: remove when verification is turned on
     42         try {
     43             TooDeep.excessiveNesting();
     44             System.err.println("excessiveNesting did not throw");
     45         } catch (VerifyError ve) {}
     46         }
     47         System.out.println("excessiveNesting ok");
     48 
     49         m.notNested();
     50         System.out.println("notNested ok");
     51 
     52         Object obj1 = new Object();
     53         Object obj2 = new Object();
     54 
     55         m.twoPath(obj1, obj2, 0);
     56         System.out.println("twoPath ok");
     57 
     58         m.triplet(obj1, obj2, 0);
     59         System.out.println("triplet ok");
     60     }
     61 
     62     /**
     63      * Recursive synchronized method.
     64      */
     65     synchronized void recursiveSync(int iter) {
     66         if (iter < 40) {
     67             recursiveSync(iter+1);
     68         } else {
     69             System.out.println("recursiveSync ok");
     70         }
     71     }
     72 
     73     /**
     74      * Tests simple nesting, with and without a throw.
     75      */
     76     void nestedMayThrow(boolean doThrow) {
     77         synchronized (this) {
     78             synchronized (Main.class) {
     79                 synchronized (new Object()) {
     80                     synchronized(Class.class) {
     81                         if (doThrow) {
     82                             throw new MyException();
     83                         }
     84                     }
     85                 }
     86             }
     87         }
     88     }
     89 
     90     /**
     91      * Exercises bug 3215458.
     92      */
     93     void constantLock() {
     94         Class thing = Thread.class;
     95         synchronized (Thread.class) {}
     96     }
     97 
     98     /**
     99      * Confirms that we can have 32 nested monitors on one method.
    100      */
    101     void notExcessiveNesting() {
    102         synchronized (this) {   // 1
    103         synchronized (this) {   // 2
    104         synchronized (this) {   // 3
    105         synchronized (this) {   // 4
    106         synchronized (this) {   // 5
    107         synchronized (this) {   // 6
    108         synchronized (this) {   // 7
    109         synchronized (this) {   // 8
    110         synchronized (this) {   // 9
    111         synchronized (this) {   // 10
    112         synchronized (this) {   // 11
    113         synchronized (this) {   // 12
    114         synchronized (this) {   // 13
    115         synchronized (this) {   // 14
    116         synchronized (this) {   // 15
    117         synchronized (this) {   // 16
    118         synchronized (this) {   // 17
    119         synchronized (this) {   // 18
    120         synchronized (this) {   // 19
    121         synchronized (this) {   // 20
    122         synchronized (this) {   // 21
    123         synchronized (this) {   // 22
    124         synchronized (this) {   // 23
    125         synchronized (this) {   // 24
    126         synchronized (this) {   // 25
    127         synchronized (this) {   // 26
    128         synchronized (this) {   // 27
    129         synchronized (this) {   // 28
    130         synchronized (this) {   // 29
    131         synchronized (this) {   // 30
    132         synchronized (this) {   // 31
    133         synchronized (this) {   // 32
    134         }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
    135     }
    136 
    137     /**
    138      * Confirms that we can have more than 32 non-nested monitors in one
    139      * method.
    140      */
    141     void notNested() {
    142         synchronized (this) {}  // 1
    143         synchronized (this) {}  // 2
    144         synchronized (this) {}  // 3
    145         synchronized (this) {}  // 4
    146         synchronized (this) {}  // 5
    147         synchronized (this) {}  // 6
    148         synchronized (this) {}  // 7
    149         synchronized (this) {}  // 8
    150         synchronized (this) {}  // 9
    151         synchronized (this) {}  // 10
    152         synchronized (this) {}  // 11
    153         synchronized (this) {}  // 12
    154         synchronized (this) {}  // 13
    155         synchronized (this) {}  // 14
    156         synchronized (this) {}  // 15
    157         synchronized (this) {}  // 16
    158         synchronized (this) {}  // 17
    159         synchronized (this) {}  // 18
    160         synchronized (this) {}  // 19
    161         synchronized (this) {}  // 20
    162         synchronized (this) {}  // 21
    163         synchronized (this) {}  // 22
    164         synchronized (this) {}  // 23
    165         synchronized (this) {}  // 24
    166         synchronized (this) {}  // 25
    167         synchronized (this) {}  // 26
    168         synchronized (this) {}  // 27
    169         synchronized (this) {}  // 28
    170         synchronized (this) {}  // 29
    171         synchronized (this) {}  // 30
    172         synchronized (this) {}  // 31
    173         synchronized (this) {}  // 32
    174         synchronized (this) {}  // 33
    175         synchronized (this) {}  // 34
    176     }
    177 
    178     /* does nothing but ensure that the compiler doesn't discard an object */
    179     private void doNothing(Object obj) {}
    180 
    181     /**
    182      * Conditionally uses one of the synchronized objects.
    183      */
    184     public void twoPath(Object obj1, Object obj2, int x) {
    185         Object localObj;
    186 
    187         synchronized (obj1) {
    188             synchronized(obj2) {
    189                 if (x == 0) {
    190                     localObj = obj2;
    191                 } else {
    192                     localObj = obj1;
    193                 }
    194             }
    195         }
    196 
    197         doNothing(localObj);
    198     }
    199 
    200     /**
    201      * Lock the monitor two or three times, and make use of the locked or
    202      * unlocked object.
    203      */
    204     public void triplet(Object obj1, Object obj2, int x) {
    205         Object localObj;
    206 
    207         synchronized (obj1) {
    208             synchronized(obj1) {
    209                 if (x == 0) {
    210                     synchronized(obj1) {
    211                         localObj = obj2;
    212                     }
    213                 } else {
    214                     localObj = obj1;
    215                 }
    216             }
    217         }
    218 
    219         doNothing(localObj);
    220     }
    221 }
    222