From: Eric Laurent Date: Fri, 29 Aug 2014 02:45:37 +0000 (-0700) Subject: sound trigger: fix cross deadlock between service and client X-Git-Tag: android-x86-6.0-r1~852^2~413^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=886561f06ddaea86a51def1e918367430240b5ac;p=android-x86%2Fframeworks-av.git sound trigger: fix cross deadlock between service and client Do not call callback methods on ISoundTriggerClient with the service mutex locked: the client implementation will lock its mutex to process the callback and if a request from the same client with client mutex locked was waiting for the service mutex a deadlock occurs. Bug: 16873049. Change-Id: Ifc3b31fdfaed525981fa59876c041478f38b42e8 --- diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index 2502e0d12f..b5aaee3d41 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -249,7 +249,7 @@ sp SoundTriggerHwService::prepareRecognitionEvent_l( event->data_offset = sizeof(struct sound_trigger_recognition_event); break; default: - return eventMemory; + return eventMemory; } size_t size = event->data_offset + event->data_size; @@ -653,7 +653,6 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp& eve { ALOGV("onCallbackEvent type %d", event->mType); - AutoMutex lock(mLock); sp eventMemory = event->mMemory; if (eventMemory == 0 || eventMemory->pointer() == NULL) { @@ -668,34 +667,53 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp& eve case CallbackEvent::TYPE_RECOGNITION: { struct sound_trigger_recognition_event *recognitionEvent = (struct sound_trigger_recognition_event *)eventMemory->pointer(); + sp client; + { + AutoMutex lock(mLock); + sp model = getModel(recognitionEvent->model); + if (model == 0) { + ALOGW("%s model == 0", __func__); + return; + } + if (model->mState != Model::STATE_ACTIVE) { + ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); + return; + } - sp model = getModel(recognitionEvent->model); - if (model == 0) { - ALOGW("%s model == 0", __func__); - return; + recognitionEvent->capture_session = model->mCaptureSession; + model->mState = Model::STATE_IDLE; + client = mClient; } - if (model->mState != Model::STATE_ACTIVE) { - ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); - return; + if (client != 0) { + client->onRecognitionEvent(eventMemory); } - - recognitionEvent->capture_session = model->mCaptureSession; - mClient->onRecognitionEvent(eventMemory); - model->mState = Model::STATE_IDLE; } break; case CallbackEvent::TYPE_SOUNDMODEL: { struct sound_trigger_model_event *soundmodelEvent = (struct sound_trigger_model_event *)eventMemory->pointer(); - - sp model = getModel(soundmodelEvent->model); - if (model == 0) { - ALOGW("%s model == 0", __func__); - return; + sp client; + { + AutoMutex lock(mLock); + sp model = getModel(soundmodelEvent->model); + if (model == 0) { + ALOGW("%s model == 0", __func__); + return; + } + client = mClient; + } + if (client != 0) { + client->onSoundModelEvent(eventMemory); } - mClient->onSoundModelEvent(eventMemory); } break; case CallbackEvent::TYPE_SERVICE_STATE: { - mClient->onServiceStateChange(eventMemory); + sp client; + { + AutoMutex lock(mLock); + client = mClient; + } + if (client != 0) { + client->onServiceStateChange(eventMemory); + } } break; default: LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);