1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  */
22 
23 /*
24  * This file is available under and governed by the GNU General Public
25  * License version 2 only, as published by the Free Software Foundation.
26  * However, the following notice accompanied the original version of this
27  * file:
28  *
29  * Written by Doug Lea with assistance from members of JCP JSR-166
30  * Expert Group and released to the public domain, as explained at
31  * http://creativecommons.org/publicdomain/zero/1.0/
32  */
33 
34 /*
35  * @test
36  * @bug 6941130
37  * @summary Numeric overflow/underflow of permits causes Error throw
38  */
39 
40 import java.util.concurrent.Semaphore;
41 
42 public class PermitOverflow {
43 
main(String[] args)44     public static void main(String[] args) throws Throwable {
45         for (boolean fair : new boolean[] { true, false }) {
46             Semaphore sem = new Semaphore(Integer.MAX_VALUE - 1, fair);
47             if (sem.availablePermits() != Integer.MAX_VALUE - 1)
48                 throw new RuntimeException();
49             try {
50                 sem.release(2);
51                 throw new RuntimeException();
52             } catch (Error expected) {
53             }
54             sem.release(1);
55             if (sem.availablePermits() != Integer.MAX_VALUE)
56                 throw new RuntimeException();
57             try {
58                 sem.release(1);
59                 throw new RuntimeException();
60             } catch (Error expected) {
61             }
62             try {
63                 sem.release(Integer.MAX_VALUE);
64                 throw new RuntimeException();
65             } catch (Error expected) {
66             }
67         }
68 
69         class Sem extends Semaphore {
70             public Sem(int permits, boolean fair) {
71                 super(permits, fair);
72             }
73             public void reducePermits(int reduction) {
74                 super.reducePermits(reduction);
75             }
76         }
77 
78         for (boolean fair : new boolean[] { true, false }) {
79             Sem sem = new Sem(Integer.MIN_VALUE + 1, fair);
80             if (sem.availablePermits() != Integer.MIN_VALUE + 1)
81                 throw new RuntimeException();
82             try {
83                 sem.reducePermits(2);
84                 throw new RuntimeException();
85             } catch (Error expected) {
86             }
87             sem.reducePermits(1);
88             if (sem.availablePermits() != Integer.MIN_VALUE)
89                 throw new RuntimeException();
90             try {
91                 sem.reducePermits(1);
92                 throw new RuntimeException();
93             } catch (Error expected) {
94             }
95             try {
96                 sem.reducePermits(Integer.MAX_VALUE);
97                 throw new RuntimeException();
98             } catch (Error expected) {
99             }
100         }
101     }
102 }
103