diff options
author | Eric Laurent <elaurent@google.com> | 2013-09-25 20:01:01 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-09-25 20:01:01 +0000 |
commit | 1802399c7c4d8557922688f246df292703f417f1 (patch) | |
tree | 5a484131d6bf93a8e9a565c20407e6e174ff228a /services | |
parent | 2b890936e978de0a8d4450ee1aaeda53d22b5f4e (diff) | |
parent | eb3c337a3d6c74ec857dfc8be7eeafe634614bcd (diff) | |
download | frameworks_av-1802399c7c4d8557922688f246df292703f417f1.zip frameworks_av-1802399c7c4d8557922688f246df292703f417f1.tar.gz frameworks_av-1802399c7c4d8557922688f246df292703f417f1.tar.bz2 |
Merge "fix deadlock in audioflinger::createEffect()" into klp-dev
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 39 | ||||
-rw-r--r-- | services/audioflinger/Effects.h | 4 |
2 files changed, 22 insertions, 21 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index f6e4c6a..e70d566 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -2102,9 +2102,6 @@ sp<IEffect> AudioFlinger::createEffect( } { - Mutex::Autolock _l(mLock); - - if (!EffectIsNullUuid(&pDesc->uuid)) { // if uuid is specified, request effect descriptor lStatus = EffectGetDescriptor(&pDesc->uuid, &desc); @@ -2177,6 +2174,15 @@ sp<IEffect> AudioFlinger::createEffect( // return effect descriptor *pDesc = desc; + if (io == 0 && sessionId == AUDIO_SESSION_OUTPUT_MIX) { + // if the output returned by getOutputForEffect() is removed before we lock the + // mutex below, the call to checkPlaybackThread_l(io) below will detect it + // and we will exit safely + io = AudioSystem::getOutputForEffect(&desc); + ALOGV("createEffect got output %d", io); + } + + Mutex::Autolock _l(mLock); // If output is not specified try to find a matching audio session ID in one of the // output threads. @@ -2190,29 +2196,20 @@ sp<IEffect> AudioFlinger::createEffect( lStatus = BAD_VALUE; goto Exit; } - if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { - // if the output returned by getOutputForEffect() is removed before we lock the - // mutex below, the call to checkPlaybackThread_l(io) below will detect it - // and we will exit safely - io = AudioSystem::getOutputForEffect(&desc); - ALOGV("createEffect got output %d", io); + // look for the thread where the specified audio session is present + for (size_t i = 0; i < mPlaybackThreads.size(); i++) { + if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) { + io = mPlaybackThreads.keyAt(i); + break; + } } if (io == 0) { - // look for the thread where the specified audio session is present - for (size_t i = 0; i < mPlaybackThreads.size(); i++) { - if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) { - io = mPlaybackThreads.keyAt(i); + for (size_t i = 0; i < mRecordThreads.size(); i++) { + if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) { + io = mRecordThreads.keyAt(i); break; } } - if (io == 0) { - for (size_t i = 0; i < mRecordThreads.size(); i++) { - if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) { - io = mRecordThreads.keyAt(i); - break; - } - } - } } // If no output thread contains the requested session ID, default to // first output. The effect chain will be moved to the correct output diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h index c35cff0..b717857 100644 --- a/services/audioflinger/Effects.h +++ b/services/audioflinger/Effects.h @@ -25,6 +25,10 @@ // state changes or resource modifications. Always respect the following order // if multiple mutexes must be acquired to avoid cross deadlock: // AudioFlinger -> ThreadBase -> EffectChain -> EffectModule +// In addition, methods that lock the AudioPolicyService mutex (getOutputForEffect(), +// startOutput()...) should never be called with AudioFlinger or Threadbase mutex locked +// to avoid cross deadlock with other clients calling AudioPolicyService methods that in turn +// call AudioFlinger thus locking the same mutexes in the reverse order. // The EffectModule class is a wrapper object controlling the effect engine implementation // in the effect library. It prevents concurrent calls to process() and command() functions |