8168751: Two "Direct Clip" threads are created to play the same "AudioClip" object, what makes clip sound corrupted
Reviewed-by: serb, amenkov
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java Fri Jan 20 16:03:08 2017 -0800
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java Mon Jan 23 19:58:06 2017 +0300
@@ -1005,15 +1005,15 @@
private static final class DirectClip extends DirectDL
implements Clip, Runnable, AutoClosingClip {
- private Thread thread;
- private byte[] audioData = null;
- private int frameSize; // size of one frame in bytes
- private int m_lengthInFrames;
- private int loopCount;
- private int clipBytePosition; // index in the audioData array at current playback
- private int newFramePosition; // set in setFramePosition()
- private int loopStartFrame;
- private int loopEndFrame; // the last sample included in the loop
+ private volatile Thread thread;
+ private volatile byte[] audioData = null;
+ private volatile int frameSize; // size of one frame in bytes
+ private volatile int m_lengthInFrames;
+ private volatile int loopCount;
+ private volatile int clipBytePosition; // index in the audioData array at current playback
+ private volatile int newFramePosition; // set in setFramePosition()
+ private volatile int loopStartFrame;
+ private volatile int loopEndFrame; // the last sample included in the loop
// auto closing clip support
private boolean autoclosing = false;
@@ -1345,7 +1345,8 @@
@Override
public void run() {
if (Printer.trace) Printer.trace(">>> DirectClip: run() threadID="+Thread.currentThread().getId());
- while (thread != null) {
+ Thread curThread = Thread.currentThread();
+ while (thread == curThread) {
// doIO is volatile, but we could check it, then get
// pre-empted while another thread changes doIO and notifies,
// before we wait (so we sleep in wait forever).
@@ -1353,7 +1354,12 @@
if (!doIO) {
try {
lock.wait();
- } catch(InterruptedException ie) {}
+ } catch(InterruptedException ie) {
+ } finally {
+ if (thread != curThread) {
+ break;
+ }
+ }
}
}
while (doIO) {