From 44afb7be73047b462e61eb451c14774d3ff7848a Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Fri, 5 Feb 2010 21:36:07 -0800 Subject: [PATCH] Fixing a race condition in the TextToSpeech service that could be triggered if many long utterances are started and interrupted in rapid succession. --- .../TtsService/src/android/tts/TtsService.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java index b7eea2e3d5bc3..bca736a2e5137 100755 --- a/packages/TtsService/src/android/tts/TtsService.java +++ b/packages/TtsService/src/android/tts/TtsService.java @@ -133,6 +133,7 @@ public class TtsService extends Service implements OnCompletionListener { private HashMap mCallbacksMap; private Boolean mIsSpeaking; + private Boolean mSynthBusy; private ArrayList mSpeechQueue; private HashMap mEarcons; private HashMap mUtterances; @@ -168,6 +169,7 @@ public class TtsService extends Service implements OnCompletionListener { mSelf = this; mIsSpeaking = false; + mSynthBusy = false; mEarcons = new HashMap(); mUtterances = new HashMap(); @@ -733,10 +735,11 @@ public class TtsService extends Service implements OnCompletionListener { try { synthAvailable = synthesizerLock.tryLock(); if (!synthAvailable) { + mSynthBusy = true; Thread.sleep(100); Thread synth = (new Thread(new SynthThread())); - //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); + mSynthBusy = false; return; } int streamType = DEFAULT_STREAM_TYPE; @@ -821,10 +824,11 @@ public class TtsService extends Service implements OnCompletionListener { try { synthAvailable = synthesizerLock.tryLock(); if (!synthAvailable) { + mSynthBusy = true; Thread.sleep(100); Thread synth = (new Thread(new SynthThread())); - //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); + mSynthBusy = false; return; } String language = ""; @@ -959,6 +963,12 @@ public class TtsService extends Service implements OnCompletionListener { private void processSpeechQueue() { boolean speechQueueAvailable = false; + synchronized (this) { + if (mSynthBusy){ + // There is already a synth thread waiting to run. + return; + } + } try { speechQueueAvailable = speechQueueLock.tryLock(SPEECHQUEUELOCK_TIMEOUT, TimeUnit.MILLISECONDS);