# HG changeset patch # User serb # Date 1536435171 25200 # Node ID dcf301c53d23151e9792b8654540917e65b7f9ae # Parent 109a94379f63420c90fee9286542b5e887f67442 8207150: Clip.isRunning() may return true after Clip.stop() was called Reviewed-by: prr diff -r 109a94379f63 -r dcf301c53d23 src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java --- a/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java Wed Sep 05 10:17:02 2018 -0700 +++ b/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java Sat Sep 08 12:32:51 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2018, 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 @@ -547,14 +547,15 @@ getEventDispatcher().addLineMonitor(this); } - doIO = true; - - // need to set Active and Started - // note: the current API always requires that - // Started and Active are set at the same time... - if (isSource && stoppedWritten) { - setStarted(true); - setActive(true); + synchronized(lock) { + doIO = true; + // need to set Active and Started + // note: the current API always requires that + // Started and Active are set at the same time... + if (isSource && stoppedWritten) { + setStarted(true); + setActive(true); + } } if (Printer.trace) Printer.trace("<< DirectDL: implStart() succeeded"); @@ -582,10 +583,10 @@ // read/write thread, that's why isStartedRunning() // cannot be used doIO = false; + setActive(false); + setStarted(false); lock.notifyAll(); } - setActive(false); - setStarted(false); stoppedWritten = false; if (Printer.trace) Printer.trace(" << DirectDL: implStop() succeeded"); @@ -731,12 +732,14 @@ if ((long)off + (long)len > (long)b.length) { throw new ArrayIndexOutOfBoundsException(b.length); } - - if (!isActive() && doIO) { - // this is not exactly correct... would be nicer - // if the native sub system sent a callback when IO really starts - setActive(true); - setStarted(true); + synchronized(lock) { + if (!isActive() && doIO) { + // this is not exactly correct... would be nicer + // if the native sub system sent a callback when IO really + // starts + setActive(true); + setStarted(true); + } } int written = 0; while (!flushing) { @@ -957,11 +960,14 @@ if ((long)off + (long)len > (long)b.length) { throw new ArrayIndexOutOfBoundsException(b.length); } - if (!isActive() && doIO) { - // this is not exactly correct... would be nicer - // if the native sub system sent a callback when IO really starts - setActive(true); - setStarted(true); + synchronized(lock) { + if (!isActive() && doIO) { + // this is not exactly correct... would be nicer + // if the native sub system sent a callback when IO really + // starts + setActive(true); + setStarted(true); + } } int read = 0; while (doIO && !flushing) { diff -r 109a94379f63 -r dcf301c53d23 test/jdk/ProblemList.txt --- a/test/jdk/ProblemList.txt Wed Sep 05 10:17:02 2018 -0700 +++ b/test/jdk/ProblemList.txt Sat Sep 08 12:32:51 2018 -0700 @@ -688,7 +688,6 @@ javax/sound/sampled/DirectAudio/bug6372428.java 8055097 generic-all javax/sound/sampled/Clip/bug5070081.java 8055097 generic-all javax/sound/sampled/DataLine/LongFramePosition.java 8055097 generic-all -javax/sound/sampled/Clip/AutoCloseTimeCheck.java 8207150 generic-all javax/sound/sampled/Clip/Drain/ClipDrain.java 7062792 generic-all diff -r 109a94379f63 -r dcf301c53d23 test/jdk/javax/sound/sampled/Clip/ClipIsRunningAfterStop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/javax/sound/sampled/Clip/ClipIsRunningAfterStop.java Sat Sep 08 12:32:51 2018 -0700 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018, 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 java.util.concurrent.TimeUnit; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; + +import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED; + +/** + * @test + * @bug 8207150 + * @summary Clip.isRunning() may return true after Clip.stop() was called + */ +public final class ClipIsRunningAfterStop { + + private static volatile Exception failed; + + public static void main(final String[] args) throws Exception { + final Runnable r = () -> { + try { + test(); + } catch (LineUnavailableException | IllegalArgumentException ignored) { + // the test is not applicable + } catch (Exception ex) { + failed = ex; + } + }; + Thread t1 = new Thread(r); + Thread t2 = new Thread(r); + Thread t3 = new Thread(r); + t1.start(); + t2.start(); + t3.start(); + t1.join(); + t2.join(); + t3.join(); + if (failed != null) { + throw new RuntimeException(failed); + } + } + + private static void test() throws Exception { + // Will run the test no more than 15 seconds + long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(15); + while (failed == null && endtime - System.nanoTime() > 0) { + Clip clip = createClip(); + clip.loop(Clip.LOOP_CONTINUOUSLY); + clip.stop(); + if (clip.isRunning()) { + if (clip.isRunning()) { + throw new RuntimeException("Clip is running"); + } + } + if (clip.isActive()) { + if (clip.isActive()) { + throw new RuntimeException("Clip is active"); + } + } + clip.close(); + } + } + + private static Clip createClip() throws LineUnavailableException { + AudioFormat format = + new AudioFormat(PCM_SIGNED, 44100, 8, 1, 1, 44100, false); + DataLine.Info info = new DataLine.Info(Clip.class, format); + Clip clip = (Clip) AudioSystem.getLine(info); + clip.open(format, new byte[2], 0, 2); + return clip; + } +}