1/*
2 * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6400879 7100140
27 * @summary Tests that Start/Stop sequence doesn't hang
28 * @author Alexey Menkov
29 * @run main/othervm bug6400879
30 */
31
32import java.util.concurrent.TimeUnit;
33
34import javax.sound.sampled.*;
35
36public class bug6400879 extends Thread {
37
38    public static void main(String args[]) throws Exception {
39        bug6400879 pThis = new bug6400879();
40        //pThis.init();
41        pThis.setDaemon(true);
42        pThis.start();
43        monitor(pThis);
44    }
45
46    static final long BLOCK_TIMEOUT = 5000;    // 5 sec
47
48    // monitors that pThis doesn't hang
49    public static void monitor(bug6400879 pThis) throws Exception {
50        long prevLoop = -1;
51        long prevTime = currentTimeMillis();
52        while (pThis.isAlive()) {
53            if (pThis.loopCounter == prevLoop) {
54                long delay = currentTimeMillis() - prevTime;
55                if (delay > BLOCK_TIMEOUT) {
56                    // blocked?
57                    log("The test is slow, delay = " + delay);
58                }
59            } else {
60                prevLoop = pThis.loopCounter;
61                prevTime = currentTimeMillis();
62            }
63            delay(1000);    // sleep for 1 sec
64        }
65        log("Test sucessfully passed.");
66    }
67
68    volatile long loopCounter = 0;
69    final long LOOPS_PER_LINE = 100;
70
71    public void run() {
72        SourceDataLine line = null;
73
74        DataLine.Info line_info = new DataLine.Info(SourceDataLine.class, null);
75        Line.Info infos[] = AudioSystem.getSourceLineInfo(line_info);
76
77        log("total " + infos.length + " lines");
78
79        for (int lineNum = 0; lineNum < infos.length; lineNum++) {
80            try {
81                line = (SourceDataLine)AudioSystem.getLine(infos[lineNum]);
82                log("testing line: " + line);
83                line.open(line.getFormat());
84                for (int i=0; i<LOOPS_PER_LINE; i++) {
85                    log("start->stop (" + i + ")");
86                    line.start();
87                    line.stop();
88                    log(" - OK");
89                    loopCounter++;
90                }
91                line.close();
92                line = null;
93            } catch (LineUnavailableException e1) {
94                log("LineUnavailableException caught, test okay.");
95                log(e1.getMessage());
96            } catch (SecurityException e2) {
97                log("SecurityException caught, test okay.");
98                log(e2.getMessage());
99            } catch (IllegalArgumentException e3) {
100                log("IllegalArgumentException caught, test okay.");
101                log(e3.getMessage());
102            }
103            if (line != null) {
104                line.close();
105                line = null;
106            }
107        }
108
109    }
110
111
112    // helper routines
113    static long startTime = currentTimeMillis();
114    static long currentTimeMillis() {
115        return TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
116    }
117    static void log(String s) {
118        long time = currentTimeMillis() - startTime;
119        long ms = time % 1000;
120        time /= 1000;
121        long sec = time % 60;
122        time /= 60;
123        long min = time % 60;
124        time /= 60;
125        System.out.println(""
126                + (time < 10 ? "0" : "") + time
127                + ":" + (min < 10 ? "0" : "") + min
128                + ":" + (sec < 10 ? "0" : "") + sec
129                + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
130                + " (" + Thread.currentThread().getName() + ") " + s);
131    }
132    static void delay(int millis) {
133        try {
134            Thread.sleep(millis);
135        } catch (InterruptedException e) {}
136    }
137}
138