jdk/test/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java
changeset 41905 e8e5df013c6e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java	Mon Oct 31 14:50:09 2016 +0300
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 2)
+ */
+public class SDLLinuxCrash implements Runnable {
+    SourceDataLine sdl;
+    int size;
+
+    SDLLinuxCrash(SourceDataLine sdl, int size) {
+        this.sdl = sdl;
+        this.size = size - (size % 4);
+    }
+
+    public void run() {
+        int written=0;
+        //byte[] buffer = new byte[4096];
+        byte[] buffer = data;
+        out("    starting data line feed thread.");
+        try {
+            while (written<size) {
+                int toWrite = buffer.length;
+                if (toWrite+written > size) {
+                    toWrite = size-written;
+                }
+                toWrite -= (toWrite % 4);
+                //out("    writing "+toWrite+" bytes.");
+                int thisWritten = sdl.write(buffer, 0, toWrite);
+                if (thisWritten<toWrite) {
+                    out("    only wrote "+thisWritten+" bytes instead of "+toWrite);
+                }
+                if (thisWritten<=0) {
+                    break;
+                }
+                written += thisWritten;
+            }
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+        out("    leaving data line feed thread.");
+    }
+
+    public static long bytes2Ms(long bytes, AudioFormat format) {
+        return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize());
+    }
+
+    static int staticLen=1000;
+    static boolean addLen=true;
+
+    public static SourceDataLine start() throws Exception {
+        AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+        if (addLen) {
+            staticLen+=(int) (staticLen/5)+1000;
+        } else {
+            staticLen-=(int) (staticLen/5)+1000;
+        }
+        if (staticLen>8*44100*4) {
+            staticLen = 8*44100*4;
+            addLen=!addLen;
+        }
+        if (staticLen<1000) {
+            staticLen = 1000;
+            addLen=!addLen;
+        }
+        int len = staticLen;
+        len -= (len % 4);
+        out("    preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio...");
+
+        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+        SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info);
+        sdl.addLineListener(new LineListener() {
+                public void update(LineEvent e) {
+                    if (e.getType() == LineEvent.Type.STOP) {
+                        out("    calling close() from event dispatcher thread");
+                        ((SourceDataLine) e.getSource()).close();
+                    }
+                    else if (e.getType() == LineEvent.Type.CLOSE) {
+                    }
+                }
+            });
+
+        out("    opening...");
+        sdl.open();
+        out("    starting...");
+        sdl.start();
+        (new Thread(new SDLLinuxCrash(sdl, len))).start();
+        return sdl;
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!isSoundcardInstalled()) {
+            return;
+        }
+
+        try {
+            int COUNT=10;
+            out();
+            out("4498848 Sound causes crashes on Linux (testing with SourceDataLine)");
+            if (args.length>0) {
+                COUNT=Integer.parseInt(args[0]);
+            }
+            for (int i=0; i<COUNT; i++) {
+                out("  trial "+(i+1)+"/"+COUNT);
+                SourceDataLine sdl = start();
+                int waitTime = 500+(1000*(i % 2)); // every 2nd time wait 1500, rather than 500ms.
+                out("    waiting for "+waitTime+" ms for audio playback to stop...");
+                Thread.sleep(waitTime);
+                out("    calling close() from main thread");
+                sdl.close();
+                // let the subsystem enough time to actually close the soundcard
+                out("    waiting for 2 seconds...");
+                Thread.sleep(2000);
+                out();
+            }
+            out("  waiting for 1 second...");
+            Thread.sleep(1000);
+        } catch (Exception e) {
+            e.printStackTrace();
+            out("  waiting for 1 second");
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {}
+            // do not fail if no audio device installed - bug 4742021
+            if (!(e instanceof LineUnavailableException)) {
+                throw e;
+            }
+        }
+        out("Test passed");
+    }
+
+    static void out() {
+        out("");
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+
+
+
+    static final byte[] data = new byte[] {
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 122, 122
+    };
+
+}