summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/AudioFlinger.cpp
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-05-26 16:03:08 -0700
committerEric Laurent <elaurent@google.com>2014-05-26 16:13:30 -0700
commitfe1a94e68e173fe4dfe7699112422a94eddacb4e (patch)
treea9443f7cb6fb34bc5015cc26fd9257d5d559f7f9 /services/audioflinger/AudioFlinger.cpp
parentc62476f0c0c1cf9283a38852bde0a4c9434df712 (diff)
downloadframeworks_av-fe1a94e68e173fe4dfe7699112422a94eddacb4e.zip
frameworks_av-fe1a94e68e173fe4dfe7699112422a94eddacb4e.tar.gz
frameworks_av-fe1a94e68e173fe4dfe7699112422a94eddacb4e.tar.bz2
audioflinger: fix deadlock upon AudioRecord creation error
AudioFlinger:openRecord() should not hold mClientLock when releasing the local reference on AudioRecord as the destructor will also lock mClientLock. Same fix for AudioFlinger::createTrack(). Also make sure that AudioFlinger::createEffect() holds mClientLock when clearing local reference to the Client in case of error. Regression introduced by 021cf9634ab09c0753a40b7c9ef4ba603be5c3da Bug: 15118096. Change-Id: Ie961c398c8e0460bca9b95e2ee4ce6859316c275
Diffstat (limited to 'services/audioflinger/AudioFlinger.cpp')
-rw-r--r--services/audioflinger/AudioFlinger.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 68fa553..9bd0e9b 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -635,8 +635,12 @@ sp<IAudioTrack> AudioFlinger::createTrack(
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the Track so that the
// Client destructor is called by the TrackBase destructor with mClientLock held
- Mutex::Autolock _cl(mClientLock);
- client.clear();
+ // Don't hold mClientLock when releasing the reference on the track as the
+ // destructor will acquire it.
+ {
+ Mutex::Autolock _cl(mClientLock);
+ client.clear();
+ }
track.clear();
goto Exit;
}
@@ -1173,7 +1177,7 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
}
// mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the
- // ThreadBase mutex and teh locknig order is ThreadBase::mLock then AudioFlinger::mClientLock.
+ // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock.
if (clientAdded) {
// the config change is always sent from playback or record threads to avoid deadlock
// with AudioSystem::gLock
@@ -1419,8 +1423,12 @@ sp<IAudioRecord> AudioFlinger::openRecord(
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the
// Client destructor is called by the TrackBase destructor with mClientLock held
- Mutex::Autolock _cl(mClientLock);
- client.clear();
+ // Don't hold mClientLock when releasing the reference on the track as the
+ // destructor will acquire it.
+ {
+ Mutex::Autolock _cl(mClientLock);
+ client.clear();
+ }
recordTrack.clear();
goto Exit;
}
@@ -2380,6 +2388,11 @@ sp<IEffect> AudioFlinger::createEffect(
if (handle != 0 && id != NULL) {
*id = handle->id();
}
+ if (handle == 0) {
+ // remove local strong reference to Client with mClientLock held
+ Mutex::Autolock _cl(mClientLock);
+ client.clear();
+ }
}
Exit: