| Index: content/browser/speech/google_one_shot_remote_engine.cc
|
| diff --git a/content/browser/speech/google_one_shot_remote_engine.cc b/content/browser/speech/google_one_shot_remote_engine.cc
|
| index 452a34a9004ec13439814185552709119cf79706..539983a7c01ccb57e8d37d8d5542b901698d4fca 100644
|
| --- a/content/browser/speech/google_one_shot_remote_engine.cc
|
| +++ b/content/browser/speech/google_one_shot_remote_engine.cc
|
| @@ -166,7 +166,8 @@ GoogleOneShotRemoteEngineConfig::~GoogleOneShotRemoteEngineConfig() {}
|
|
|
| GoogleOneShotRemoteEngine::GoogleOneShotRemoteEngine(
|
| net::URLRequestContextGetter* context)
|
| - : url_context_(context) {
|
| + : url_context_(context),
|
| + url_fetcher_destroyed_(false) {
|
| }
|
|
|
| GoogleOneShotRemoteEngine::~GoogleOneShotRemoteEngine() {}
|
| @@ -178,7 +179,7 @@ void GoogleOneShotRemoteEngine::SetConfig(
|
|
|
| void GoogleOneShotRemoteEngine::StartRecognition() {
|
| DCHECK(delegate());
|
| - DCHECK(!url_fetcher_.get());
|
| + DCHECK(!url_fetcher_.get() || url_fetcher_destroyed_);
|
| std::string lang_param = config_.language;
|
|
|
| if (lang_param.empty() && url_context_) {
|
| @@ -229,15 +230,31 @@ void GoogleOneShotRemoteEngine::StartRecognition() {
|
| url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
|
| net::LOAD_DO_NOT_SEND_COOKIES |
|
| net::LOAD_DO_NOT_SEND_AUTH_DATA);
|
| + url_fetcher_destroyed_ = false;
|
| url_fetcher_->Start();
|
| }
|
|
|
| void GoogleOneShotRemoteEngine::EndRecognition() {
|
| - url_fetcher_.reset();
|
| + // TODO(primiano) URLFetcher(Core) seems to be currently broken. In particular
|
| + // I am experiencing a failure in the case of a recognition suddenly aborted,
|
| + // with a DCHECK in content::URLFetcherCore::CompleteAddingUploadDataChunk().
|
| + // What happens is that this method (thus the url_fetcher dtor) might be
|
| + // called immediately after an AppendChunkToUpload. AppendChunkToUpload is
|
| + // not executed synchronously (inside URLFetcher) but defers its work to a
|
| + // posted task. However, it seems to me that the posted routine
|
| + // (CompleteAddingUploadDataChunk) does not take into account the corner case
|
| + // in which the URLFetcher is destructed in the meanwhile (which in turn
|
| + // causes a Stop() call on URLFetcherCore)
|
| + // Therefore I am currently commenting the .reset() call and adding the
|
| + // url_fetcher_destroyed_ workaround (read hack). This should not cause any
|
| + // memory leak due to the scoped_ptr smart pointer.
|
| +
|
| + // url_fetcher_.reset();
|
| + url_fetcher_destroyed_ = true;
|
| }
|
|
|
| void GoogleOneShotRemoteEngine::TakeAudioChunk(const AudioChunk& data) {
|
| - DCHECK(url_fetcher_.get());
|
| + DCHECK(url_fetcher_.get() && !url_fetcher_destroyed_);
|
| DCHECK(encoder_.get());
|
| DCHECK_EQ(data.bytes_per_sample(), config_.audio_num_bits_per_sample / 8);
|
| encoder_->Encode(data);
|
| @@ -246,7 +263,7 @@ void GoogleOneShotRemoteEngine::TakeAudioChunk(const AudioChunk& data) {
|
| }
|
|
|
| void GoogleOneShotRemoteEngine::AudioChunksEnded() {
|
| - DCHECK(url_fetcher_.get());
|
| + DCHECK(url_fetcher_.get() && !url_fetcher_destroyed_);
|
| DCHECK(encoder_.get());
|
|
|
| // UploadAudioChunk requires a non-empty final buffer. So we encode a packet
|
| @@ -269,6 +286,8 @@ void GoogleOneShotRemoteEngine::AudioChunksEnded() {
|
|
|
| void GoogleOneShotRemoteEngine::OnURLFetchComplete(
|
| const content::URLFetcher* source) {
|
| + if (url_fetcher_destroyed_)
|
| + return;
|
| DCHECK_EQ(url_fetcher_.get(), source);
|
| SpeechRecognitionResult result;
|
| SpeechRecognitionError error(content::SPEECH_RECOGNITION_ERROR_NETWORK);
|
| @@ -291,7 +310,7 @@ void GoogleOneShotRemoteEngine::OnURLFetchComplete(
|
| }
|
|
|
| bool GoogleOneShotRemoteEngine::IsRecognitionPending() const {
|
| - return url_fetcher_ != NULL;
|
| + return url_fetcher_ != NULL && !url_fetcher_destroyed_;
|
| }
|
|
|
| int GoogleOneShotRemoteEngine::GetDesiredAudioChunkDurationMs() const {
|
|
|