JDK-8168751 : Two "Direct Clip" threads are created to play the same "AudioClip" object, what makes clip sound corrupted
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.sound
  • Affected Version: 6u141,7u131,8u112,9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • CPU: generic
  • Submitted: 2016-10-26
  • Updated: 2017-11-29
  • Resolved: 2017-01-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10 JDK 6 JDK 7 JDK 8 JDK 9
10Fixed 6u181Fixed 7u171Fixed 8u152Fixed 9 b155Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
64-bit JDK 8u112 b15, 64-bit JDK 9 b145

ADDITIONAL OS VERSION INFORMATION :
64-bit MS Windows 7 OS

A DESCRIPTION OF THE PROBLEM :
After many repetitive sequential calls to the methods "loop()", "stop()" on the same instance of "java.applet.AudioClip" at some moment two threads with the name "Direct Clip", which are responsible for background playing of the mentioned "AudioClip" instance, are created and start existing in parallel, what makes the being played clip sound as corrupted.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The bug is intermittent and can be reproduced with both 64-bit and 32-bit JDK using 2 test cases:
- The attached "TestCase2.zip" ��� it may take 12 minutes to reproduce.
- The attached "AC.java" (requires additional changes), "Windows Logon Sound.wav" ��� it may take hours to reproduce.

Using the test case "TestCase2.zip":
1. Decompress the attached test case "TestCase2.zip".
2. Start command line "cmd.exe" and change a current directory to the extracted "TestCase2" directory.
3. Compile and run the extracted test case "TestCase2.java". It may take 12 minutes to reproduce the bug. The bug is reproduced, if call stacks of 2 existing threads with "Direct Clip" name become printed out in the command line, for example:

-------------------- Example test case output in the command line --------------------
[Thread[Direct Clip,6,main]], thread.getId()='46'
                at java.base@9-internal/java.lang.Object.wait(Native Method)
                at java.desktop@9-internal/com.sun.media.sound.DirectAudioDevice$DirectDL.write(DirectAudioDevice.java:763)
                at java.desktop@9-internal/com.sun.media.sound.DirectAudioDevice$DirectClip.run(DirectAudioDevice.java:1374)
                at java.base@9-internal/java.lang.Thread.run(Thread.java:844)

[Thread[Direct Clip,6,main]], thread.getId()='45'
                at java.base@9-internal/java.lang.Object.wait(Native Method)
                at java.desktop@9-internal/com.sun.media.sound.DirectAudioDevice$DirectDL.write(DirectAudioDevice.java:763)
                at java.desktop@9-internal/com.sun.media.sound.DirectAudioDevice$DirectClip.run(DirectAudioDevice.java:1374)
                at java.base@9-internal/java.lang.Thread.run(Thread.java:844)
----------------------------------------
Comments
The bug was also reproduced with JDK 7u131 b12, JDK 6u141 b12 and with JDK 7, JDK 6 compiled from the latest version of their development source code, therefore adding "7u131", "6u141" to "Affects Version/s" field of the bug.
06-02-2017

Review thread: http://mail.openjdk.java.net/pipermail/sound-dev/2017-January/000506.html
18-01-2017

The thread with the name "Direct Clip" is represented by the instance variable declared as "private Thread thread" in the class "com.sun.media.sound.DirectAudioDevice.DirectClip" from the file "jdk9/client/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java". The instance variable "thread" is assigned a non-null value, which is a newly created "Direct Clip" thread, in the method "com.sun.media.sound.DirectAudioDevice.DirectClip.open()". And the null value is assigned to "thread" instance variable in the method "com.sun.media.sound.DirectAudioDevice.DirectClip.implClose()" to make the currently running "Direct Clip" thread complete execution, by means of the condition "while (thread != null) {" in the thread's "run" method "DirectAudioDevice.DirectClip.run()". The root cause of the bug consists of 2 parts: Part 1 The fact that "DirectClip.thread" instance variable is not thread-safe. There is a possibility that null value assigned to it in one thread through the former mentioned "DirectClip.implClose()" method does not become visible for the running "Direct Clip" thread in the method "DirectClip.run()". Part 2 In the method "DirectClip.run()" not taking into account the fact that a new "Direct Clip" thread could have already been started and assigned to "DirectClip.thread" instance variable after the call to "DirectClip.implClose()" by the moment when "DirectClip.thread" value is checked for null in "DirectClip.run()" method.
18-01-2017

The test case was attached to the bug record as "TestCase2.zip" file. The bug was reproduced using this test case with: - 64-bit JDK 9 b145, 32-bit JDK 9 compiled from the latest version of "jdk9/client" forest. - 64-bit JDK 8u112 b15, and 32-bit JDK 8 compiled from the latest version of "jdk8u-dev" forest.
18-01-2017

Returning "Priority" field value to "P3", because the issue is not a showstopper, a JCK test failure, a crash, a vulnerability. Also it is even not known on which exact version of JDK 8 the issue was reproduced.
23-11-2016