diff options
author | Eric Laurent <elaurent@google.com> | 2014-11-19 19:04:52 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2014-11-20 09:15:02 -0800 |
commit | 0ebd5f95b68a3a5c9e5509f21938c9e51e74d71b (patch) | |
tree | 0a2939a70644eb37c401705c8211d65bac553743 /services | |
parent | 18899808001ddaea13fa4c5277502c96351f69a5 (diff) | |
download | frameworks_av-0ebd5f95b68a3a5c9e5509f21938c9e51e74d71b.zip frameworks_av-0ebd5f95b68a3a5c9e5509f21938c9e51e74d71b.tar.gz frameworks_av-0ebd5f95b68a3a5c9e5509f21938c9e51e74d71b.tar.bz2 |
AudioSystem: fix cross deadlock
Do not hold gLockAPS when calling
AudioPolicyService::registerClient() in get_audio_policy_service().
registerClient() will need to acquire the AudioPolicyService mutex and
if at the same time a method called from AudioPolicyService
(with mutex held) calls back into AudioSystem and get_audio_policy_service()
a cross deadlock occurs.
Same preventive fix for get_audio_flinger().
Use a separate mutex for notification client list in AudioPolicyService.
This prevents deadlocking if registerClient() is called as a consequence of
AudioFlinger calling back into AudioPolicyManager while executing a method
with AudioPolicyService locked
Bug: 18403952.
Bug: 18450065.
Change-Id: Ia832e41aede8bc6c843fc615508fbdd74e0863b5
Diffstat (limited to 'services')
-rw-r--r-- | services/audiopolicy/AudioPolicyService.cpp | 17 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.h | 2 |
2 files changed, 11 insertions, 8 deletions
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp index dd4067f..6a4a669 100644 --- a/services/audiopolicy/AudioPolicyService.cpp +++ b/services/audiopolicy/AudioPolicyService.cpp @@ -149,7 +149,7 @@ AudioPolicyService::~AudioPolicyService() void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) { - Mutex::Autolock _l(mLock); + Mutex::Autolock _l(mNotificationClientsLock); uid_t uid = IPCThreadState::self()->getCallingUid(); if (mNotificationClients.indexOfKey(uid) < 0) { @@ -168,14 +168,17 @@ void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& cli // removeNotificationClient() is called when the client process dies. void AudioPolicyService::removeNotificationClient(uid_t uid) { - Mutex::Autolock _l(mLock); - - mNotificationClients.removeItem(uid); - + { + Mutex::Autolock _l(mNotificationClientsLock); + mNotificationClients.removeItem(uid); + } #ifndef USE_LEGACY_AUDIO_POLICY + { + Mutex::Autolock _l(mLock); if (mAudioPolicyManager) { mAudioPolicyManager->clearAudioPatches(uid); } + } #endif } @@ -186,7 +189,7 @@ void AudioPolicyService::onAudioPortListUpdate() void AudioPolicyService::doOnAudioPortListUpdate() { - Mutex::Autolock _l(mLock); + Mutex::Autolock _l(mNotificationClientsLock); for (size_t i = 0; i < mNotificationClients.size(); i++) { mNotificationClients.valueAt(i)->onAudioPortListUpdate(); } @@ -212,7 +215,7 @@ status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle void AudioPolicyService::doOnAudioPatchListUpdate() { - Mutex::Autolock _l(mLock); + Mutex::Autolock _l(mNotificationClientsLock); for (size_t i = 0; i < mNotificationClients.size(); i++) { mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); } diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index 4e68ab1..f1db309 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -495,7 +495,7 @@ private: AudioPolicyClient *mAudioPolicyClient; DefaultKeyedVector< uid_t, sp<NotificationClient> > mNotificationClients; - + Mutex mNotificationClientsLock; // protects mNotificationClients // Manage all effects configured in audio_effects.conf sp<AudioPolicyEffects> mAudioPolicyEffects; audio_mode_t mPhoneState; |