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
40import java.util.concurrent.Semaphore;
41
42public class PermitOverflow {
43
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