Skip to content

Commit 70574ef

Browse files
pszcAndroid (Google) Code Review
authored andcommitted
Fix threading issue in BlockingAudioTrack.
This fixes the issue where one thread calls .stop() on mAudioTrack that was released (or being released) by other thread. Bug: 7029291 Change-Id: Ia6db803e8ee40379b63327acf578466127cfabcb
1 parent c5fd6e5 commit 70574ef

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

core/java/android/speech/tts/BlockingAudioTrack.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ class BlockingAudioTrack {
6969

7070
// Need to be seen by stop() which can be called from another thread. mAudioTrack will be
7171
// set to null only after waitAndRelease().
72-
private volatile AudioTrack mAudioTrack;
72+
private Object mAudioTrackLock = new Object();
73+
private AudioTrack mAudioTrack;
7374
private volatile boolean mStopped;
7475

7576
BlockingAudioTrack(int streamType, int sampleRate,
@@ -93,7 +94,9 @@ class BlockingAudioTrack {
9394

9495
public boolean init() {
9596
AudioTrack track = createStreamingAudioTrack();
96-
mAudioTrack = track;
97+
synchronized (mAudioTrackLock) {
98+
mAudioTrack = track;
99+
}
97100

98101
if (track == null) {
99102
return false;
@@ -103,24 +106,34 @@ public boolean init() {
103106
}
104107

105108
public void stop() {
106-
AudioTrack track = mAudioTrack;
107-
if (track != null) {
108-
track.stop();
109+
synchronized (mAudioTrackLock) {
110+
if (mAudioTrack != null) {
111+
mAudioTrack.stop();
112+
}
113+
mStopped = true;
109114
}
110-
mStopped = true;
111115
}
112116

113117
public int write(byte[] data) {
114-
if (mAudioTrack == null || mStopped) {
118+
AudioTrack track = null;
119+
synchronized (mAudioTrackLock) {
120+
track = mAudioTrack;
121+
}
122+
123+
if (track == null || mStopped) {
115124
return -1;
116125
}
117-
final int bytesWritten = writeToAudioTrack(mAudioTrack, data);
126+
final int bytesWritten = writeToAudioTrack(track, data);
127+
118128
mBytesWritten += bytesWritten;
119129
return bytesWritten;
120130
}
121131

122132
public void waitAndRelease() {
123-
AudioTrack track = mAudioTrack;
133+
AudioTrack track = null;
134+
synchronized (mAudioTrackLock) {
135+
track = mAudioTrack;
136+
}
124137
if (track == null) {
125138
if (DBG) Log.d(TAG, "Audio track null [duplicate call to waitAndRelease ?]");
126139
return;
@@ -152,8 +165,10 @@ public void waitAndRelease() {
152165
// all data from the audioTrack has been sent to the mixer, so
153166
// it's safe to release at this point.
154167
if (DBG) Log.d(TAG, "Releasing audio track [" + track.hashCode() + "]");
168+
synchronized(mAudioTrackLock) {
169+
mAudioTrack = null;
170+
}
155171
track.release();
156-
mAudioTrack = null;
157172
}
158173

159174

0 commit comments

Comments
 (0)