summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2011-07-19 12:43:17 +0100
committerNarayan Kamath <narayan@google.com>2011-07-19 12:43:17 +0100
commita36cce06a63ff0eb1c3a765ceb3863195732b4bf (patch)
tree6343989381976cfd91532d4cbea33ea907c65bf9
parent90e5650f96dabadaaf141beae20a646855073ae1 (diff)
downloadframeworks_base-a36cce06a63ff0eb1c3a765ceb3863195732b4bf.zip
frameworks_base-a36cce06a63ff0eb1c3a765ceb3863195732b4bf.tar.gz
frameworks_base-a36cce06a63ff0eb1c3a765ceb3863195732b4bf.tar.bz2
Fix a threading issue in AudioPlaybackHandler
Never allow the AudioTrack to be observed in a state where it is release()d but non null. Change-Id: I1e5b61355f30c2aafcd55ecdf83077d7a9d99c66
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java36
1 files changed, 22 insertions, 14 deletions
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 96864c4..255b333 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -418,22 +418,30 @@ class AudioPlaybackHandler {
if (DBG) Log.d(TAG, "handleSynthesisDone()");
final AudioTrack audioTrack = params.getAudioTrack();
- try {
- if (audioTrack != null) {
- if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
- audioTrack.hashCode());
- blockUntilDone(params);
- if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
- // The last call to AudioTrack.write( ) will return only after
- // all data from the audioTrack has been sent to the mixer, so
- // it's safe to release at this point.
- audioTrack.release();
- }
- } finally {
+ if (audioTrack == null) {
+ return;
+ }
+
+ if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
+ audioTrack.hashCode());
+ blockUntilDone(params);
+ if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
+
+ // The last call to AudioTrack.write( ) will return only after
+ // all data from the audioTrack has been sent to the mixer, so
+ // it's safe to release at this point. Make sure release() and the call
+ // that set the audio track to null are performed atomically.
+ synchronized (this) {
+ // Never allow the audioTrack to be observed in a state where
+ // it is released but non null. The only case this might happen
+ // is in the various stopFoo methods that call AudioTrack#stop from
+ // different threads, but they are synchronized on AudioPlayBackHandler#this
+ // too.
+ audioTrack.release();
params.setAudioTrack(null);
- params.getDispatcher().dispatchUtteranceCompleted();
- mLastSynthesisRequest = null;
}
+ params.getDispatcher().dispatchUtteranceCompleted();
+ mLastSynthesisRequest = null;
}
private static void blockUntilDone(SynthesisMessageParams params) {